root/modules/luascript.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. chdk_luai_numdiv
  2. chdk_luai_nummod
  3. lua_script_disable_yield_hook
  4. lua_script_enable_yield_hook
  5. lua_create_usb_msg
  6. lua_script_reset
  7. lua_script_error_ptp
  8. lua_count_hook
  9. lua_script_error
  10. lua_script_finish
  11. lua_script_start
  12. lua_script_start_file
  13. lua_script_run
  14. lua_run_restore
  15. lua_get_key_arg
  16. on_off_value_from_lua_arg
  17. luaCB_set_curve_state
  18. luaCB_get_curve_state
  19. luaCB_set_curve_file
  20. luaCB_get_curve_file
  21. luaCB_set_aelock
  22. luaCB_set_aflock
  23. luaCB_set_mf
  24. luaCB_get_sd_over_modes
  25. luaCB_shoot
  26. action_stack_AS_LUA_SLEEP
  27. sleep_delay
  28. luaCB_sleep
  29. luaCB_keyfunc
  30. luaCB_cls
  31. luaCB_set_console_layout
  32. luaCB_set_console_autoredraw
  33. luaCB_console_redraw
  34. luaCB_get_partitionInfo
  35. luaCB_swap_partitions
  36. luaCB_get_av96
  37. luaCB_get_bv96
  38. luaCB_get_day_seconds
  39. luaCB_get_disk_size
  40. luaCB_get_dofinfo
  41. luaCB_get_free_disk_space
  42. luaCB_get_focus
  43. luaCB_get_iso_market
  44. luaCB_get_iso_mode
  45. luaCB_get_iso_real
  46. luaCB_get_jpg_count
  47. luaCB_get_prop
  48. luaCB_get_prop_str
  49. luaCB_get_raw_support
  50. luaCB_get_raw_count
  51. luaCB_get_sv96
  52. luaCB_get_tick_count
  53. luaCB_get_exp_count
  54. luaCB_get_image_dir
  55. luaCB_get_tv96
  56. luaCB_get_user_av_id
  57. luaCB_get_user_av96
  58. luaCB_get_min_av96
  59. luaCB_get_max_av96
  60. luaCB_get_current_av96
  61. luaCB_get_current_tv96
  62. luaCB_get_nd_value_ev96
  63. luaCB_get_nd_current_ev96
  64. luaCB_get_imager_active
  65. luaCB_get_user_tv_id
  66. luaCB_get_user_tv96
  67. luaCB_get_vbatt
  68. luaCB_get_zoom
  69. luaCB_get_parameter_data
  70. luaCB_get_flash_params_count
  71. luaCB_set_av96_direct
  72. luaCB_set_av96
  73. luaCB_set_focus_interlock_bypass
  74. luaCB_set_focus
  75. luaCB_set_iso_mode
  76. luaCB_set_iso_real
  77. luaCB_set_led
  78. luaCB_set_nd_filter
  79. luaCB_set_prop
  80. luaCB_set_prop_str
  81. luaCB_set_raw_nr
  82. luaCB_get_raw_nr
  83. luaCB_set_raw
  84. luaCB_get_raw
  85. luaCB_set_sv96
  86. luaCB_set_tv96_direct
  87. luaCB_set_tv96
  88. luaCB_set_user_av_by_id_rel
  89. luaCB_set_user_av_by_id
  90. luaCB_set_user_av96
  91. luaCB_set_user_tv_by_id_rel
  92. luaCB_set_user_tv_by_id
  93. luaCB_set_user_tv96
  94. luaCB_set_zoom_speed
  95. luaCB_set_zoom_rel
  96. luaCB_set_zoom
  97. action_stack_AS_LUA_WAIT_CLICK
  98. luaCB_wait_click
  99. luaCB_is_pressed
  100. luaCB_is_key
  101. luaCB_set_exit_key
  102. luaCB_wheel_right
  103. luaCB_wheel_left
  104. luaCB_md_af_led_control
  105. luaCB_md_get_cell_diff
  106. luaCB_md_get_cell_val
  107. luaCB_md_detect_motion
  108. return_string_selected
  109. action_stack_AS_WAIT_MODULE
  110. luaCB_file_browser
  111. luaCB_textbox
  112. luaCB_draw_pixel
  113. luaCB_draw_line
  114. luaCB_draw_rect
  115. luaCB_draw_rect_filled
  116. luaCB_draw_ellipse
  117. luaCB_draw_ellipse_filled
  118. luaCB_draw_string
  119. luaCB_draw_clear
  120. luaCB_get_gui_screen_width
  121. luaCB_get_gui_screen_height
  122. luaCB_autostarted
  123. luaCB_get_autostart
  124. luaCB_set_autostart
  125. luaCB_get_usb_power
  126. luaCB_set_remote_timing
  127. luaCB_usb_force_active
  128. luaCB_usb_sync_wait
  129. luaCB_enter_alt
  130. luaCB_exit_alt
  131. luaCB_get_alt_mode
  132. luaCB_shut_down
  133. luaCB_print_screen
  134. luaCB_get_movie_status
  135. luaCB_set_movie_status
  136. luaCB_get_video_button
  137. luaCB_get_video_recording
  138. luaCB_get_drive_mode
  139. luaCB_get_focus_mode
  140. luaCB_get_focus_state
  141. luaCB_get_focus_ok
  142. luaCB_get_flash_mode
  143. luaCB_get_shooting
  144. luaCB_get_flash_ready
  145. luaCB_get_IS_mode
  146. luaCB_get_orientation_sensor
  147. luaCB_get_zoom_steps
  148. luaCB_get_nd_present
  149. luaCB_get_propset
  150. luaCB_get_ev
  151. luaCB_set_ev
  152. luaCB_get_histo_range
  153. luaCB_shot_histo_enable
  154. luaCB_shot_histo_write_to_file
  155. luaCB_get_live_histo
  156. luaCB_play_sound
  157. luaCB_get_temperature
  158. luaCB_get_time
  159. luaCB_peek
  160. luaCB_poke
  161. luaCB_bitand
  162. luaCB_bitor
  163. luaCB_bitxor
  164. luaCB_bitshl
  165. luaCB_bitshri
  166. luaCB_bitshru
  167. luaCB_bitnot
  168. set_string_field
  169. set_number_field
  170. luaCB_get_buildinfo
  171. luaCB_get_mode
  172. luaCB_set_raw_develop
  173. luaCB_raw_merge_start
  174. luaCB_raw_merge_add_file
  175. luaCB_raw_merge_end
  176. luaCB_set_backlight
  177. luaCB_set_lcd_display
  178. luaCB_set_draw_title_line
  179. luaCB_get_draw_title_line
  180. levent_id_from_lua_arg
  181. levent_index_from_id_lua_arg
  182. luaCB_get_levent_def
  183. luaCB_get_levent_index
  184. luaCB_get_levent_def_by_index
  185. luaCB_post_levent_to_ui
  186. luaCB_post_levent_for_npt
  187. luaCB_set_levent_active
  188. luaCB_set_levent_script_mode
  189. luaCB_set_capture_mode_canon
  190. luaCB_set_capture_mode
  191. luaCB_is_capture_mode_valid
  192. luaCB_set_record
  193. luaCB_switch_mode_usb
  194. pack_native_args
  195. luaCB_call_func_ptr
  196. luaCB_call_event_proc
  197. luaCB_reboot
  198. luaCB_get_config_value
  199. luaCB_set_config_value
  200. luaCB_set_config_autosave
  201. luaCB_save_config_file
  202. luaCB_load_config_file
  203. luaCB_set_file_attributes
  204. action_stack_AS_SCRIPT_READ_USB_MSG
  205. action_stack_AS_SCRIPT_WRITE_USB_MSG
  206. luaCB_read_usb_msg
  207. luaCB_write_usb_msg
  208. set_meminfo_num
  209. luaCB_get_meminfo
  210. luaCB_set_yield
  211. luaCB_get_usb_capture_support
  212. luaCB_init_usb_capture
  213. luaCB_get_usb_capture_target
  214. luaCB_set_usb_capture_timeout
  215. luaCB_iso_to_sv96
  216. luaCB_sv96_to_iso
  217. luaCB_iso_real_to_market
  218. luaCB_iso_market_to_real
  219. luaCB_sv96_real_to_market
  220. luaCB_sv96_market_to_real
  221. luaCB_aperture_to_av96
  222. luaCB_av96_to_aperture
  223. luaCB_usec_to_tv96
  224. luaCB_tv96_to_usec
  225. luaCB_seconds_to_tv96
  226. luaCB_shoot_hook_set
  227. luaCB_shoot_hook_is_ready
  228. luaCB_shoot_hook_continue
  229. luaCB_shoot_hook_count
  230. register_shoot_hook_fn
  231. register_shoot_hooks
  232. register_lua_funcs
  233. lua_set_variable
  234. lua_set_as_ret

   1 #include "camera_info.h"
   2 #include "stdlib.h"
   3 #include "gui.h"
   4 #include "gui_draw.h"
   5 #include "script.h"
   6 #include "script_key_funcs.h"
   7 #include "conf.h"
   8 #include "shot_histogram.h"
   9 #include "raw.h"
  10 #include "levent.h"
  11 #include "console.h"
  12 #include "action_stack.h"
  13 #include "ptp_chdk.h"
  14 #include "lang.h"
  15 #include "gui_lang.h"
  16 #include "histogram.h"
  17 #include "shooting.h"
  18 #include "autoiso.h"
  19 #include "remotecap.h"
  20 #include "battery.h"
  21 #include "temperature.h"
  22 #include "backlight.h"
  23 #include "keyboard.h"
  24 #include "shutdown.h"
  25 #include "sound.h"
  26 #include "modes.h"
  27 #include "sd_card.h"
  28 #include "clock.h"
  29 #include "lens.h"
  30 #include "properties.h"
  31 #include "file_counter.h"
  32 #include "debug_led.h"
  33 #include "meminfo.h"
  34 #include "callfunc.h"
  35 #include "usb_remote.h"
  36 
  37 #include "script_api.h"
  38 #include "curves.h"
  39 #include "motion_detector.h"
  40 #include "raw_merge.h"
  41 #include "gui_fselect.h"
  42 #include "gui_tbox.h"
  43 #include "module_def.h"
  44 #include "luascript.h"
  45 #include "script_shoot_hook.h"
  46 #include "rawhookops.h"
  47 
  48 #include "../lib/lua/lualib.h"
  49 #include "../lib/lua/lauxlib.h"
  50 #include "../lib/lua/lstate.h"  // for L->nCcalls, baseCcalls
  51 
  52 #ifdef THUMB_FW
  53 // provide div and mod behavior similar to preivous CPUs for digic 6, instead of triggering exception handler
  54 // used in lua core, see luaconf.h
  55 int chdk_luai_numdiv(int a, int b) {
  56     if(!a) {
  57        return 0;
  58     }
  59     if(b) {
  60         return a/b;
  61     }
  62     if(a>0) {
  63         return 0x7FFFFFFF;
  64     } else {
  65         return 0x80000000;
  66     }
  67 }
  68 int chdk_luai_nummod(int a, int b) {
  69     if(!b) {
  70        return 0;
  71     }
  72     return a%b;
  73 }
  74 #endif
  75 
  76 lua_State* L;
  77 lua_State* Lt;
  78 
  79 extern void register_lua_funcs( lua_State* L );
  80 
  81 static int lua_script_is_ptp;
  82 static int ptp_saved_alt_state;
  83 static int run_first_resume; // 1 first 'resume', 0 = resuming from yield
  84 static int run_start_tick; // tick count at start of this kbd_task iteration
  85 static int run_hook_count; // number of calls to the count hook this kbd_task iteration
  86 #define YIELD_CHECK_COUNT 100 // check for yield every N vm instructions
  87 #define YIELD_MAX_COUNT_DEFAULT 25 // 25 checks = 2500 vm instructions
  88 #define YIELD_MAX_MS_DEFAULT 10
  89 static unsigned yield_max_count;
  90 static unsigned yield_max_ms;
  91 static int yield_hook_enabled;
  92 
  93 static void lua_script_disable_yield_hook(void) {
  94     yield_hook_enabled = 0;
  95 }
  96 static void lua_script_enable_yield_hook(void) {
  97     yield_hook_enabled = 1;
  98 }
  99 
 100 // create a ptp message from the given stack index
 101 // incompatible types will return a TYPE_UNSUPPORTED message
 102 static ptp_script_msg *lua_create_usb_msg( lua_State* L, int index, unsigned msgtype) {
 103     // TODO maybe we should just pass the lua type constants
 104     unsigned datatype, datasize = 4;
 105     int ivalue = 0;
 106     void *data = &ivalue;
 107     int ltype = lua_type(L,index);
 108     switch(ltype) {
 109         case LUA_TNONE:
 110             return NULL; // nothing on the stack, no message generated
 111         break;
 112         case LUA_TNIL:
 113             datatype = PTP_CHDK_TYPE_NIL;
 114         break;
 115         case LUA_TBOOLEAN:
 116             datatype = PTP_CHDK_TYPE_BOOLEAN;
 117             ivalue = lua_toboolean(L,index);
 118         break;
 119         case LUA_TNUMBER:
 120             datatype = PTP_CHDK_TYPE_INTEGER;
 121             ivalue = lua_tonumber(L,index);
 122         break;
 123         case LUA_TSTRING:
 124             datatype = PTP_CHDK_TYPE_STRING;
 125             data = (char *)lua_tolstring(L,index,&datasize);
 126         break;
 127         // TODO this uses usb_msg_table_to_string to serialize the table
 128         // the default format is described in
 129         // http://chdk.setepontos.com/index.php?topic=4338.msg62606#msg62606
 130         // other formats can be implemented by overriding this function in your lua code
 131         case LUA_TTABLE: {
 132             int result;
 133             lua_script_disable_yield_hook(); // don't want to yield while converting
 134             lua_getglobal(L, "usb_msg_table_to_string"); // push function
 135             lua_pushvalue(L, index); // copy specified index to top of stack
 136             result = lua_pcall(L,1,1,0); // this will leave an error message as a string on the stack if call fails
 137             lua_script_enable_yield_hook();
 138             if( result ) {
 139                 // if called from lua, throw a normal error
 140                 if( msgtype == PTP_CHDK_S_MSGTYPE_USER ) {
 141                     luaL_error(L,lua_tostring(L,-1));
 142                     return NULL; // not reached
 143                 } else { // if it's a return, convert the message to an ERR
 144                     msgtype = PTP_CHDK_S_MSGTYPE_ERR;
 145                     datatype = PTP_CHDK_S_ERRTYPE_RUN;
 146                     data = (char *)lua_tolstring(L,-1,&datasize);
 147                     break;
 148                 }
 149             }
 150             // an empty table is returned as an empty string by default
 151             // a non-string should never show up here
 152             if ( !lua_isstring(L,-1) ) { 
 153                 return NULL;
 154             }
 155             datatype = PTP_CHDK_TYPE_TABLE;
 156             data = (char *)lua_tolstring(L,-1,&datasize);
 157             lua_pop(L,1);
 158         }
 159         break;
 160         default:
 161             datatype = PTP_CHDK_TYPE_UNSUPPORTED;
 162             data = (char *)lua_typename(L,ltype); // return type name as message data
 163             datasize = strlen(data);
 164     }
 165     return ptp_script_create_msg(msgtype,datatype,datasize,data);
 166 }
 167 
 168 void lua_script_reset()
 169 {
 170     script_shoot_hooks_reset();
 171     lua_close( L );
 172     L = 0;
 173 }
 174 
 175 void lua_script_error_ptp(int runtime, const char *err) {
 176     if(runtime) {
 177         ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, err);
 178     } else {
 179         ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_COMPILE, err);
 180         lua_script_reset();
 181     }
 182 }
 183 
 184 static void lua_count_hook(lua_State *L, lua_Debug *ar)
 185 {
 186     run_hook_count++;
 187     if( L->nCcalls > L->baseCcalls || !yield_hook_enabled )
 188         return;
 189     if(run_hook_count >= yield_max_count || get_tick_count() - run_start_tick >= yield_max_ms)
 190         lua_yield( L, 0 );
 191 }
 192 
 193 int lua_script_error(lua_State *Lt,int runtime)
 194 {
 195     const char *err = lua_tostring( Lt, -1 );
 196 
 197     if(err)
 198     {
 199         if(!*err)
 200         {
 201             script_console_add_error( (long)"ERROR: empty error message" );
 202         }
 203         else
 204         {
 205             script_console_add_error( (long)err );
 206         }
 207     }
 208     else
 209     {
 210         script_console_add_error( (long)"ERROR: NULL error message" );
 211     }
 212 
 213     if (lua_script_is_ptp)
 214     {
 215         lua_script_error_ptp(runtime,err);
 216     }
 217     else
 218     {
 219         if (runtime)
 220         {
 221             if(conf.debug_lua_restart_on_error) {
 222                 script_end();
 223                 script_start_gui(0);
 224                 return SCRIPT_RUN_RUNNING;
 225             }
 226         }
 227         else // ensure lua_state is closed for compiletime errors
 228         {
 229             lua_script_reset();
 230         }
 231     }
 232 
 233     script_console_add_error(LANG_CONSOLE_TEXT_TERMINATED);
 234     return SCRIPT_RUN_ERROR;
 235 }
 236 
 237 
 238 // TODO more stuff from script.c should be moved here
 239 void lua_script_finish(lua_State *L) 
 240 {
 241     if(lua_script_is_ptp) {
 242         // send all return values as RET messages
 243         int i,end = lua_gettop(L);
 244         for(i=1;i<=end; i++) {
 245             ptp_script_msg *msg = lua_create_usb_msg(L,i,PTP_CHDK_S_MSGTYPE_RET);
 246             // if the queue is full return values will be silently discarded
 247             // incompatible types will be returned as TYPE_UNSUPPORTED to preserve expected number and order of return values
 248             if(msg) {
 249                 ptp_script_write_msg(msg); 
 250                 // create_usb_msg may convert the message to an error
 251                 if(msg->type != PTP_CHDK_S_MSGTYPE_RET) {
 252                     break;
 253                 }
 254             } else {
 255                 ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, "error creating return msg");
 256                 break;
 257             }
 258         }
 259         if(!ptp_saved_alt_state) {
 260             exit_alt();
 261         }
 262     }
 263 }
 264 
 265 int lua_script_start( char const* script, int ptp )
 266 {
 267     script_shoot_hooks_reset();
 268     lua_script_is_ptp = ptp;
 269     if(ptp) {
 270         ptp_saved_alt_state = (camera_info.state.gui_mode_alt);
 271         // put ui in alt state to allow key presses to be sent to script
 272         // just setting kbd_blocked leaves UI in a confused state
 273         if(!ptp_saved_alt_state) {
 274             enter_alt();
 275         }
 276     }
 277     L = lua_open();
 278     luaL_openlibs( L );
 279     register_lua_funcs( L );
 280 
 281     Lt = lua_newthread( L );
 282     lua_setfield( L, LUA_REGISTRYINDEX, "Lt" );
 283     if( luaL_loadstring( Lt, script ) != 0 )
 284     {
 285         lua_script_error(Lt,0);
 286         return 0;
 287     }
 288     lua_sethook(Lt, lua_count_hook, LUA_MASKCOUNT, YIELD_CHECK_COUNT );
 289     lua_script_enable_yield_hook();
 290     run_first_resume = 1;
 291     yield_max_count = YIELD_MAX_COUNT_DEFAULT;
 292     yield_max_ms = YIELD_MAX_MS_DEFAULT;
 293     return 1;
 294 }
 295 
 296 int lua_script_start_file(char const* filename)
 297 {
 298     static char loader[256];
 299     char *wrapper = "";
 300     if ((script_version.major == 1) && (script_version.minor == 3))
 301         wrapper = "require'wrap13' ";
 302     sprintf(loader, "%slocal s,e=loadfile'%s' collectgarbage() if not s then error(e) end s()", wrapper, filename);
 303     return lua_script_start(loader, 0);
 304 }
 305 
 306 // run a timeslice of lua script
 307 int lua_script_run(void)
 308 {
 309     int Lres;
 310     int top;
 311     if (run_first_resume) {
 312         run_first_resume = 0;
 313         top = 0;
 314     } else {
 315         top = lua_gettop(Lt);
 316     }
 317     run_start_tick = get_tick_count();
 318     run_hook_count = 0;
 319     Lres = lua_resume( Lt, top );
 320 
 321     if (Lres == LUA_YIELD)
 322     {
 323         // yielded
 324     }
 325     else if (Lres != 0)
 326     {
 327         return lua_script_error(Lt,1);
 328     }
 329     else 
 330     {
 331         // finished normally, add ptp result
 332         lua_script_finish(Lt);
 333         // Display 'Finished message', unless running from PTP
 334         if (lua_script_is_ptp == 0)
 335             script_console_add_error(LANG_CONSOLE_TEXT_FINISHED);
 336         return SCRIPT_RUN_ENDED;
 337     }
 338 
 339     return SCRIPT_RUN_RUNNING;
 340 }
 341 
 342 // run the "restore" function at the end of a script
 343 // Mimic uBasic logic, return 0 to trigger script interrupt immediately
 344 int lua_run_restore()
 345 {
 346     lua_getglobal(Lt, "restore");
 347     if (lua_isfunction(Lt, -1)) {
 348         if (lua_pcall( Lt, 0, 0, 0 )) {
 349             script_console_add_line( (long)lua_tostring( Lt, -1 ) );
 350         }
 351         if (lua_script_is_ptp == 0)
 352             script_console_add_error(LANG_CONSOLE_TEXT_FINISHED);
 353     }
 354     return 0;
 355 }
 356 
 357 // get key ID of key name at arg, throw error if invalid
 358 static int lua_get_key_arg( lua_State * L, int narg )
 359 {
 360     int k = script_keyid_by_name( luaL_checkstring( L, narg ) );
 361     if(!k) 
 362         luaL_error( L, "unknown key" );
 363     return k;
 364 }
 365 
 366 /*
 367   get a value where boolean or 0/!0 are accepted for on/off.
 368   normal lua toboolean will convert 0 to true, but ubasic and c users 
 369   will expect 0 to be off
 370   intentional HACK: numbers greater than 1 are returned as is
 371 */
 372 static unsigned on_off_value_from_lua_arg( lua_State* L, int index)
 373 {
 374   if( lua_isboolean(L,index) ) {
 375     return lua_toboolean(L,index);
 376   }
 377   else {
 378     return luaL_checknumber(L,index); 
 379   }
 380 }
 381 
 382 static int luaCB_set_curve_state( lua_State* L )
 383 {
 384     libcurves->curve_set_mode(luaL_checknumber( L, 1 ));
 385     return 0;
 386 }
 387 
 388 static int luaCB_get_curve_state( lua_State* L )
 389 {
 390     lua_pushnumber(L,conf.curve_enable);
 391     return 1;
 392 }
 393 
 394 static int luaCB_set_curve_file( lua_State* L )
 395 {
 396     size_t l;
 397     const char *s = luaL_checklstring(L, 1, &l);
 398     libcurves->curve_set_file(s);
 399     return 0;
 400 }
 401 
 402 static int luaCB_get_curve_file( lua_State* L )
 403 {
 404     lua_pushstring(L,conf.curve_file);
 405     return 1;
 406 }
 407 
 408 static int luaCB_set_aelock(lua_State* L) 
 409 {
 410   int val = on_off_value_from_lua_arg(L, 1);
 411   if (val>0) DoAELock();  // 1: enable AELock
 412   else UnlockAE();       // 0: disable unlock AE
 413   return 0;
 414 }
 415 
 416 static int luaCB_set_aflock(lua_State* L) 
 417 {
 418   int val = on_off_value_from_lua_arg(L, 1);
 419   if (val>0) DoAFLock();  // 1: enable AFLock
 420   else UnlockAF();       // 0: disable unlock AF
 421   return 0;
 422 }
 423 
 424 static int luaCB_set_mf(lua_State* L) 
 425 {
 426   int val = on_off_value_from_lua_arg(L, 1);
 427   if (val>0) val=DoMFLock();  // 1: enable
 428   else val=UnlockMF();       // 0: disable
 429   lua_pushnumber(L, val); 
 430   return 1; 
 431 }
 432 
 433 static int luaCB_get_sd_over_modes( lua_State* L )
 434 {
 435     lua_pushnumber(L,sd_over_modes());
 436     return 1;
 437 }
 438 
 439 static int luaCB_shoot( lua_State* L )
 440 {
 441   action_push_shoot(luaL_optnumber( L, 1, 1 ));
 442   return lua_yield( L, 0 );
 443 }
 444 
 445 // Process a sleep function from the stack
 446 static int action_stack_AS_LUA_SLEEP()
 447 {
 448     if (get_tick_count() >= action_top(2))
 449     {
 450         action_pop_func(1);
 451         return 1;
 452     }
 453     return 0;
 454 }
 455 
 456 static int sleep_delay(int delay)
 457 {
 458     /* delay of -1 signals indefinite (actually 1 day) delay */
 459     if (delay == -1)
 460         delay = 86400000;
 461 
 462     if (delay > 0)
 463         return delay + get_tick_count();
 464 
 465     return 0;
 466 }
 467 
 468 static int luaCB_sleep( lua_State* L )
 469 {
 470     int delay = sleep_delay(luaL_checknumber( L, 1 ));
 471 
 472     if (delay > 0)
 473     {
 474         action_push(delay);
 475         action_push_func(action_stack_AS_LUA_SLEEP);
 476     }
 477 
 478     return lua_yield( L, 0 );
 479 }
 480 
 481 // for press,release and click
 482 static int luaCB_keyfunc( lua_State* L )
 483 {
 484   void* func = lua_touserdata( L, lua_upvalueindex(1) );
 485   ((void(*)(long))func)( lua_get_key_arg( L, 1 ) );
 486   return lua_yield( L, 0 );
 487 }
 488 
 489 static int luaCB_cls( lua_State* L )
 490 {
 491   console_clear();
 492   return 0;
 493 }
 494 
 495 static int luaCB_set_console_layout( lua_State* L )
 496 {
 497   console_set_layout(luaL_checknumber( L, 1 ),luaL_checknumber( L, 2 ),luaL_checknumber( L, 3 ),luaL_checknumber( L, 4 ));
 498   return 0;
 499 }
 500 
 501 static int luaCB_set_console_autoredraw( lua_State* L )
 502 {
 503   console_set_autoredraw(luaL_checknumber( L, 1 ));
 504   return 0;
 505 }
 506 
 507 static int luaCB_console_redraw( lua_State* L )
 508 {
 509   console_redraw();
 510   return 0;
 511 }
 512 
 513 static int luaCB_get_partitionInfo( lua_State* L )
 514 {
 515     if (camera_info.cam_has_multipart)
 516     {
 517       lua_createtable(L, 0, 4);
 518       SET_INT_FIELD("count",  get_part_count());
 519       SET_INT_FIELD("active", get_active_partition());
 520       SET_INT_FIELD("type",   get_part_type());
 521       SET_INT_FIELD("size",   GetTotalCardSpaceKb()>>10);
 522       return 1;
 523     }
 524     return 0;
 525 }
 526 
 527 static int luaCB_swap_partitions( lua_State* L )
 528 {
 529     if (camera_info.cam_has_multipart)
 530     {
 531       int partNr;
 532 
 533       if( lua_gettop(L)==1 )
 534       {
 535         partNr = luaL_checknumber(L, 1);
 536       }
 537       else
 538       {
 539         int partCount = get_part_count();
 540         partNr = get_active_partition()+1;
 541         if( partNr > partCount ) partNr = 1;
 542       }
 543       lua_pushboolean(L, swap_partitions(partNr));
 544       return 1;
 545     }
 546     return 0;
 547 }
 548 
 549 static int luaCB_get_av96( lua_State* L )
 550 {
 551   lua_pushnumber( L, shooting_get_av96() );
 552   return 1;
 553 }
 554 
 555 static int luaCB_get_bv96( lua_State* L )
 556 {
 557   lua_pushnumber( L, shooting_get_bv96() );
 558   return 1;
 559 }
 560 
 561 static int luaCB_get_day_seconds( lua_State* L )
 562 {
 563     struct tm *ttm;
 564     ttm = get_localtime();
 565     lua_pushnumber( L, ttm->tm_hour * 3600 + ttm->tm_min * 60 + ttm->tm_sec );
 566     return 1;
 567 }
 568 
 569 static int luaCB_get_disk_size( lua_State* L )
 570 {
 571   lua_pushnumber( L, GetTotalCardSpaceKb() );
 572   return 1;
 573 }
 574 
 575 static int luaCB_get_dofinfo( lua_State* L )
 576 {
 577   shooting_update_dof_values();
 578   lua_createtable(L, 0, 12);
 579   SET_BOOL_FIELD("hyp_valid", (camera_info.dof_values.hyperfocal_valid!=0));
 580   SET_BOOL_FIELD("focus_valid", (camera_info.dof_values.distance_valid!=0));
 581   SET_INT_FIELD("aperture", camera_info.dof_values.aperture_value);
 582   SET_INT_FIELD("coc", camera_info.circle_of_confusion);
 583   SET_INT_FIELD("focal_length", camera_info.dof_values.focal_length);
 584   SET_INT_FIELD("eff_focal_length", get_effective_focal_length(lens_get_zoom_point()));
 585   SET_INT_FIELD("focus", camera_info.dof_values.subject_distance);
 586   SET_INT_FIELD("near", camera_info.dof_values.near_limit);
 587   SET_INT_FIELD("far", camera_info.dof_values.far_limit);
 588   SET_INT_FIELD("hyp_dist", camera_info.dof_values.hyperfocal_distance);
 589   SET_INT_FIELD("dof", camera_info.dof_values.depth_of_field);
 590   SET_INT_FIELD("min_stack_dist", camera_info.dof_values.min_stack_distance);
 591   return 1;
 592 }
 593 
 594 static int luaCB_get_free_disk_space( lua_State* L )
 595 {
 596   lua_pushnumber( L, GetFreeCardSpaceKb() );
 597   return 1;
 598 }
 599 
 600 static int luaCB_get_focus( lua_State* L )
 601 {
 602   lua_pushnumber( L, shooting_get_subject_distance() );
 603   return 1;
 604 }
 605 
 606 static int luaCB_get_iso_market( lua_State* L )
 607 {
 608   lua_pushnumber( L, shooting_get_iso_market() );
 609   return 1;
 610 }
 611 
 612 static int luaCB_get_iso_mode( lua_State* L )
 613 {
 614   lua_pushnumber( L, shooting_get_iso_mode() );
 615   return 1;
 616 }
 617 
 618 static int luaCB_get_iso_real( lua_State* L )
 619 {
 620   lua_pushnumber( L, shooting_get_iso_real() );
 621   return 1;
 622 }
 623 
 624 static int luaCB_get_jpg_count( lua_State* L )
 625 {
 626   lua_pushnumber( L, GetJpgCount() );
 627   return 1;
 628 }
 629 
 630 /*
 631 val=get_prop(id)
 632 get propcase value identified by id
 633 the propcase is read as a short and sign extended to an int
 634 */
 635 static int luaCB_get_prop( lua_State* L )
 636 {
 637   lua_pushnumber( L, shooting_get_prop( luaL_checknumber( L, 1 ) ) );
 638   return 1;
 639 }
 640 
 641 /*
 642 val=get_prop_str(prop_id,length)
 643 get the value of a propertycase as a string
 644 numeric values may be extracted using string.byte or or the binstr.lua module
 645 returns the value as a string, or false if the underlying propcase call returned non-zero
 646 */
 647 static int luaCB_get_prop_str( lua_State* L ) {
 648     void *buf;
 649     unsigned size;
 650     unsigned prop_id = luaL_checknumber( L, 1 );
 651     size = luaL_checknumber( L, 2 );
 652     buf = malloc(size);
 653     if(!buf) {
 654         return luaL_error( L, "malloc failed in luaCB_get_prop" );
 655     }
 656     if(get_property_case(prop_id,buf,size) == 0) {
 657         lua_pushlstring( L, buf, size );
 658     } else {
 659         lua_pushboolean( L, 0);
 660     }
 661     free(buf);
 662     return 1;
 663 }
 664 
 665 /*
 666 b=get_raw_support()
 667 return true if in rec mode and raw data is available in the current capture mode
 668 NOTE
 669 currently returns true in dedicated video modes, even if still shooting is not possible
 670 */
 671 static int luaCB_get_raw_support( lua_State* L )
 672 {
 673   lua_pushboolean( L, is_raw_possible() && !camera_info.state.mode_play );
 674   return 1;
 675 }
 676 
 677 static int luaCB_get_raw_count( lua_State* L )
 678 {
 679   lua_pushnumber( L, GetRawCount() );
 680   return 1;
 681 }
 682 
 683 static int luaCB_get_sv96( lua_State* L )
 684 {
 685   lua_pushnumber( L, shooting_get_sv96_real() );
 686   return 1;
 687 }
 688 
 689 static int luaCB_get_tick_count( lua_State* L )
 690 {
 691   lua_pushnumber( L, get_tick_count() );
 692   return 1;
 693 }
 694 
 695 static int luaCB_get_exp_count( lua_State* L )
 696 {
 697   lua_pushnumber( L, get_exposure_counter() );
 698   return 1;
 699 }
 700 
 701 static int luaCB_get_image_dir( lua_State* L )
 702 {
 703   char dir[32];
 704   get_target_dir_name(dir);
 705   lua_pushstring( L, dir );
 706   return 1;
 707 }
 708 
 709 static int luaCB_get_tv96( lua_State* L )
 710 {
 711   lua_pushnumber( L, shooting_get_tv96() );
 712   return 1;
 713 }
 714 
 715 static int luaCB_get_user_av_id( lua_State* L )
 716 {
 717   lua_pushnumber( L, shooting_get_user_av_id() );
 718   return 1;
 719 }
 720 
 721 static int luaCB_get_user_av96( lua_State* L )
 722 {
 723   lua_pushnumber( L, shooting_get_user_av96() );
 724   return 1;
 725 }
 726 
 727 // get minimum valid av96 value (widest aperture), or nil if in playback or no iris
 728 static int luaCB_get_min_av96( lua_State* L )
 729 {
 730   short av=shooting_get_min_av96(); 
 731   if(av < 0) { // -1 = Av not available
 732     lua_pushnil(L);
 733   } else {
 734     lua_pushnumber( L, av );
 735   }
 736   return 1;
 737 }
 738 
 739 // get maximum valid av96 value (smallest aperture), or nil if in playback or no iris
 740 static int luaCB_get_max_av96( lua_State* L )
 741 {
 742   short av=shooting_get_max_av96(); 
 743   if(av < 0) { // -1 = Av not available
 744     lua_pushnil(L);
 745   } else {
 746     lua_pushnumber( L, av );
 747   }
 748   return 1;
 749 }
 750 
 751 // get current av96 value - actual current value, not from half press propcase
 752 static int luaCB_get_current_av96( lua_State* L )
 753 {
 754   lua_pushnumber( L, shooting_get_current_av96() );
 755   return 1;
 756 }
 757 
 758 // get current tv96 value - actual current value, not from half press propcase
 759 // returns nil if image sensor not active (playback, sleep mode, etc)
 760 static int luaCB_get_current_tv96( lua_State* L )
 761 {
 762   long tv = shooting_get_current_tv96();
 763   if( tv == SHOOTING_TV96_INVALID) {
 764     lua_pushnil(L);
 765   } else {
 766     lua_pushnumber( L, tv);
 767   }
 768   return 1;
 769 }
 770 
 771 // get the exposure value of the ND filter, or 0 if not present
 772 static int luaCB_get_nd_value_ev96( lua_State* L )
 773 {
 774   lua_pushnumber( L, shooting_get_nd_value_ev96() );
 775   return 1;
 776 }
 777 
 778 // get the current ND value: 0 if out or not present, or nd_value if in
 779 static int luaCB_get_nd_current_ev96( lua_State* L )
 780 {
 781   lua_pushnumber( L, shooting_get_nd_current_ev96() );
 782   return 1;
 783 }
 784 
 785 // return true if sensor is enabled (live view on), false if not (playback, rec with display off, display off power save)
 786 static int luaCB_get_imager_active( lua_State* L )
 787 {
 788   lua_pushboolean( L, shooting_get_imager_active() );
 789   return 1;
 790 }
 791 
 792 static int luaCB_get_user_tv_id( lua_State* L )
 793 {
 794   lua_pushnumber( L, shooting_get_user_tv_id() );
 795   return 1;
 796 }
 797 
 798 static int luaCB_get_user_tv96( lua_State* L )
 799 {
 800   lua_pushnumber( L, shooting_get_user_tv96() );
 801   return 1;
 802 }
 803 
 804 static int luaCB_get_vbatt( lua_State* L )
 805 {
 806   lua_pushnumber( L, stat_get_vbatt() );
 807   return 1;
 808 }
 809 
 810 static int luaCB_get_zoom( lua_State* L )
 811 {
 812   lua_pushnumber( L, shooting_get_zoom() );
 813   return 1;
 814 }
 815 
 816 static int luaCB_get_parameter_data( lua_State* L )
 817 {
 818   unsigned size;
 819   unsigned id = luaL_checknumber( L, 1 );
 820   unsigned val;
 821 
 822   size = get_parameter_size(id);
 823   if (size == 0) {
 824     // return nil
 825     return 0;
 826   }
 827   if (size >= 1 && size <= 4) {
 828     val = 0;
 829     get_parameter_data( id, &val, size );
 830     lua_pushlstring( L, (char *)&val, size );
 831     // for convenience, params that fit in a number are returned in one as a second result
 832     lua_pushnumber( L, val );
 833     return 2;
 834   }
 835   else {
 836     char *buf = malloc(size);
 837     if(!buf) {
 838       luaL_error( L, "malloc failed in luaCB_get_parameter_data" );
 839     }
 840     get_parameter_data( id, buf, size );
 841     lua_pushlstring( L, buf, size );
 842     free(buf);
 843     return 1;
 844   }
 845 }
 846 
 847 static int luaCB_get_flash_params_count( lua_State* L )
 848 {
 849   lua_pushnumber( L, get_flash_params_count() );
 850   return 1;
 851 }
 852 
 853 static int luaCB_set_av96_direct( lua_State* L )
 854 {
 855   shooting_set_av96_direct( luaL_checknumber( L, 1 ), shooting_in_progress()?SET_NOW:SET_LATER );
 856   return 0;
 857 }
 858 
 859 static int luaCB_set_av96( lua_State* L )
 860 {
 861   shooting_set_av96( luaL_checknumber( L, 1 ), shooting_in_progress()?SET_NOW:SET_LATER );
 862   return 0;
 863 }
 864 
 865 static int luaCB_set_focus_interlock_bypass( lua_State* L )
 866 {
 867     set_focus_bypass(on_off_value_from_lua_arg( L, 1 ));
 868     return 0;
 869 }
 870 
 871 static int luaCB_set_focus( lua_State* L )
 872 {
 873     int sd = luaL_checknumber( L, 1 );
 874     // if sd override not available now, fail immediately without calling set_focus
 875     // to avoid unexpected results with SET_LATER
 876     if(!shooting_can_focus())
 877     {
 878         lua_pushboolean(L, 0);
 879         return 1;
 880     }
 881     // NOTE duplicated in modules/luascript.c and lib/ubasic/ubasic.c
 882     // in AF lock or MF (canon or set by MF functions), set focus now
 883     if (shooting_get_prop(camera_info.props.af_lock) 
 884       || shooting_get_focus_mode()
 885       || camera_info.state.mode_video)  // TODO video needs to be investigated, carried over from old code
 886     {
 887       shooting_set_focus(sd, SET_NOW);
 888     }
 889     else
 890     {
 891       // in an AF mode, set later
 892       shooting_set_focus(sd, SET_LATER);
 893     }
 894     lua_pushboolean(L, 1); 
 895     return 1; 
 896 }
 897 
 898 static int luaCB_set_iso_mode( lua_State* L )
 899 {
 900   shooting_set_iso_mode( luaL_checknumber( L, 1 ) );
 901   return 0;
 902 }
 903 
 904 static int luaCB_set_iso_real( lua_State* L )
 905 {
 906   shooting_set_iso_real( luaL_checknumber( L, 1 ),  shooting_in_progress()?SET_NOW:SET_LATER );
 907   return 0;
 908 }
 909 
 910 static int luaCB_set_led( lua_State* L )
 911 {
 912   int to, to1, to2;
 913   to = luaL_checknumber( L, 1 );
 914   to1 = luaL_checknumber( L, 2 );
 915   to2 = 200;
 916   if( lua_isnumber( L, 3 ) )
 917     to2 = lua_tonumber( L, 3 );
 918   camera_set_led(to, to1, to2);
 919   return 0;
 920 }
 921 
 922 static int luaCB_set_nd_filter( lua_State* L )
 923 {
 924   shooting_set_nd_filter_state( luaL_checknumber( L, 1 ), shooting_in_progress()?SET_NOW:SET_LATER );
 925   return 0;
 926 }
 927 
 928 /*
 929 set_prop(id,value)
 930 the value is treated as a short
 931 */
 932 static int luaCB_set_prop( lua_State* L )
 933 {
 934   shooting_set_prop(luaL_checknumber( L, 1 ), luaL_checknumber( L, 2 ));
 935   return 0;
 936 }
 937 
 938 /*
 939 status=set_prop_str(prop_id,value)
 940 set propertycase value as a string. Length is taken from the string
 941 numeric propcase values may be assembled by setting byte values using string.char or the binstr module
 942 status: boolean - true if the underlying propcase call returns 0, otherwise false
 943 */
 944 static int luaCB_set_prop_str( lua_State *L ) {
 945     int prop_id;
 946     unsigned len;
 947     const char *str;
 948     prop_id = luaL_checknumber( L, 1 );
 949     str = luaL_checklstring( L, 2, &len );
 950     if(str && len > 0) {
 951         lua_pushboolean( L, (set_property_case(prop_id,(void *)str,len) == 0));
 952     } else {
 953         return luaL_error( L, "invalid value");
 954     }
 955     return 1;
 956 }
 957 
 958 static int luaCB_set_raw_nr( lua_State* L )
 959 {
 960   conf.raw_nr = luaL_checknumber( L, 1 );
 961   return 0;
 962 }
 963 
 964 static int luaCB_get_raw_nr( lua_State* L )
 965 {
 966   lua_pushnumber( L, conf.raw_nr );
 967   return 1;
 968 }
 969 
 970 static int luaCB_set_raw( lua_State* L )
 971 {
 972   conf.save_raw = on_off_value_from_lua_arg( L, 1 );
 973   return 0;
 974 }
 975 
 976 static int luaCB_get_raw( lua_State* L )
 977 {
 978     lua_pushboolean( L, conf.save_raw );
 979     return 1;
 980 }
 981 
 982 static int luaCB_set_sv96( lua_State* L )
 983 {
 984   shooting_set_sv96(luaL_checknumber( L, 1 ), shooting_in_progress()?SET_NOW:SET_LATER );
 985   return 0;
 986 }
 987 
 988 static int luaCB_set_tv96_direct( lua_State* L )
 989 {
 990   shooting_set_tv96_direct(luaL_checknumber( L, 1 ), shooting_in_progress()?SET_NOW:SET_LATER );
 991   return 0;
 992 }
 993 
 994 static int luaCB_set_tv96( lua_State* L )
 995 {
 996   shooting_set_tv96(luaL_checknumber( L, 1 ), shooting_in_progress()?SET_NOW:SET_LATER );
 997   return 0;
 998 }
 999 
1000 static int luaCB_set_user_av_by_id_rel( lua_State* L )
1001 {
1002   shooting_set_user_av_by_id_rel(luaL_checknumber( L, 1 ));
1003   return 0;
1004 }
1005 
1006 static int luaCB_set_user_av_by_id( lua_State* L )
1007 {
1008   shooting_set_user_av_by_id(luaL_checknumber( L, 1 ));
1009   return 0;
1010 }
1011 
1012 static int luaCB_set_user_av96( lua_State* L )
1013 {
1014   shooting_set_user_av96(luaL_checknumber( L, 1 ));
1015   return 0;
1016 }
1017 
1018 static int luaCB_set_user_tv_by_id_rel( lua_State* L )
1019 {
1020   shooting_set_user_tv_by_id_rel(luaL_checknumber( L, 1 ));
1021   return 0;
1022 }
1023 
1024 static int luaCB_set_user_tv_by_id( lua_State* L )
1025 {
1026   shooting_set_user_tv_by_id(luaL_checknumber( L, 1 ));
1027   return 0;
1028 }
1029 
1030 static int luaCB_set_user_tv96( lua_State* L )
1031 {
1032   shooting_set_user_tv96(luaL_checknumber( L, 1 ));
1033   return 0;
1034 }
1035 
1036 static int luaCB_set_zoom_speed( lua_State* L )
1037 {
1038   shooting_set_zoom_speed(luaL_checknumber( L, 1 ));
1039   return 0;
1040 }
1041 
1042 static int luaCB_set_zoom_rel( lua_State* L )
1043 {
1044   shooting_set_zoom_rel(luaL_checknumber( L, 1 ));
1045   return 0;
1046 }
1047 
1048 static int luaCB_set_zoom( lua_State* L )
1049 {
1050   shooting_set_zoom(luaL_checknumber( L, 1 ));
1051   return 0;
1052 }
1053 
1054 // Wait for a button to be pressed and released (or the timeout to expire)
1055 static int action_stack_AS_LUA_WAIT_CLICK()
1056 {
1057     // Check key pressed or timeout
1058     if ((get_tick_count() >= action_top(2)) || camera_info.state.kbd_last_clicked)
1059     {
1060         // If timed out set key state to "no_key", otherwise key pressed so set last checked time
1061         if (!camera_info.state.kbd_last_clicked)
1062             camera_info.state.kbd_last_clicked=0xFFFF;
1063         else
1064             camera_info.state.kbd_last_checked_time = camera_info.state.kbd_last_clicked_time;
1065 
1066         action_pop_func(1);
1067         return 1;
1068     }
1069 
1070     return 0;
1071 }
1072 
1073 static int luaCB_wait_click( lua_State* L )
1074 {
1075     int delay = luaL_optnumber( L, 1, 0 );
1076     if (delay == 0) delay = -1;
1077     delay = sleep_delay(delay);
1078 
1079     // Reset 'clicked' key if it has not changed since last time
1080     if (camera_info.state.kbd_last_clicked_time <= camera_info.state.kbd_last_checked_time)
1081     {
1082         camera_info.state.kbd_last_clicked = 0;
1083     }
1084 
1085     // Set up for wait or click testing
1086     action_push(delay);
1087     action_push_func(action_stack_AS_LUA_WAIT_CLICK);
1088 
1089     // Check for short delay or key already pressed by calling action stack routine once now
1090     if (action_stack_AS_LUA_WAIT_CLICK() == 0)
1091     {
1092         return lua_yield( L, 0 );
1093     }
1094 
1095     return 0;
1096 }
1097 
1098 static int luaCB_is_pressed( lua_State* L )
1099 {
1100   lua_pushboolean( L, script_key_is_pressed(lua_get_key_arg( L, 1 )));
1101   return 1;
1102 }
1103 
1104 static int luaCB_is_key( lua_State* L )
1105 {
1106   lua_pushboolean( L, script_key_is_clicked(lua_get_key_arg( L, 1 )));
1107   return 1;
1108 }
1109 
1110 static int luaCB_set_exit_key( lua_State* L )
1111 {
1112   // TODO can't check if valid for this camera
1113   script_set_terminate_key(lua_get_key_arg( L, 1 ),luaL_checkstring( L, 1));
1114   return 0;
1115 }
1116 
1117 static int luaCB_wheel_right( lua_State* L )
1118 {
1119   JogDial_CW();
1120   return 0;
1121 }
1122 
1123 static int luaCB_wheel_left( lua_State* L )
1124 {
1125   JogDial_CCW();
1126   return 0;
1127 }
1128 
1129 static int luaCB_md_af_led_control( lua_State* L )
1130 {
1131     camera_info.perf.md_af_on_delay = luaL_checknumber( L, 1 );
1132     camera_info.perf.md_af_on_time = luaL_checknumber( L, 2 );
1133     if ((camera_info.perf.md_af_on_time > 0) && (camera_info.cam_af_led >= 0)) {
1134         camera_info.perf.md_af_tuning = 1;        // Enable MD testing with AF LED
1135         // clear previous values
1136         memset(&camera_info.perf.af_led,0,sizeof(camera_info.perf.af_led));
1137         camera_info.perf.af_led.min = 0xFFFFFFFF;
1138     } else {
1139         camera_info.perf.md_af_tuning = 0;        // Disable MD testing
1140     }
1141     return 0;
1142 }
1143 
1144 static int luaCB_md_get_cell_diff( lua_State* L )
1145 {
1146     lua_pushnumber( L, libmotiondetect->md_get_cell_diff(luaL_checknumber(L,1), luaL_checknumber(L,2)));
1147     return 1;
1148 }
1149 
1150 
1151 static int luaCB_md_get_cell_val( lua_State* L )
1152 {
1153     lua_pushnumber( L, libmotiondetect->md_get_cell_val(luaL_checknumber(L,1), luaL_checknumber(L,2)));
1154     return 1;
1155 }
1156 
1157 static int luaCB_md_detect_motion( lua_State* L )
1158 {
1159     int columns = (luaL_optnumber(L,1,6));
1160     int rows = (luaL_optnumber(L,2,4));
1161     int pixel_measure_mode = (luaL_optnumber(L,3,1));
1162     int detection_timeout = (luaL_optnumber(L,4,10000));
1163     int measure_interval = (luaL_optnumber(L,5,7));
1164     int threshold = (luaL_optnumber(L,6,10));
1165     int draw_grid = (luaL_optnumber(L,7,1));
1166     // arg 8 is the return value in ubasic. We
1167     // ignore it here. - AUJ
1168     int clipping_region_mode = (luaL_optnumber(L,9,0));
1169     int clipping_region_column1 = (luaL_optnumber(L,10,0));
1170     int clipping_region_row1 = (luaL_optnumber(L,11,0));
1171     int clipping_region_column2 = (luaL_optnumber(L,12,0));
1172     int clipping_region_row2 = (luaL_optnumber(L,13,0));
1173     int parameters = (luaL_optnumber(L,14,1));
1174     int pixels_step = (luaL_optnumber(L,15,6));
1175     int msecs_before_trigger = (luaL_optnumber(L,16,0));
1176 
1177     if (libmotiondetect->md_init_motion_detector(
1178         columns, rows, pixel_measure_mode, detection_timeout, 
1179         measure_interval, threshold, draw_grid,
1180         clipping_region_mode,
1181         clipping_region_column1, clipping_region_row1,
1182         clipping_region_column2, clipping_region_row2,
1183         parameters, pixels_step, msecs_before_trigger
1184         ))
1185         return lua_yield(L, 0);
1186     else
1187         return luaL_error( L, "md_init_motion_detector failed" );
1188 }
1189 
1190 static void return_string_selected(const char *str) {
1191     // Reconnect button input to script - will also signal action stack
1192     // that file browser / textbox is finished and return last selected file
1193     // to script caller
1194     camera_info.state.state_kbd_script_run = SCRIPT_STATE_RAN;
1195 
1196     // Push selected file as script return value
1197     lua_pushstring( Lt, (str && str[0])? str : NULL );
1198 }
1199 
1200 static int action_stack_AS_WAIT_MODULE()
1201 {
1202     // state_kbd_script_run is set to 0 when the file browser is started from a Lua script
1203     // it is reset back to 1 when the file browser exits and control is returned back to
1204     // the script
1205     if (camera_info.state.state_kbd_script_run)
1206     {
1207         action_pop_func(0);
1208     }
1209     return 0;
1210 }
1211 
1212 static int luaCB_file_browser( lua_State* L ) {
1213     // Disconnect button input from script so buttons will work in file browser
1214     camera_info.state.state_kbd_script_run = SCRIPT_STATE_INACTIVE;
1215     // Push file browser action onto stack - will loop doing nothing until file browser exits
1216     action_push_func(action_stack_AS_WAIT_MODULE);
1217     // Switch to file browser gui mode. Path can be supplied in call or defaults to "A" (root directory).
1218     libfselect->file_select(LANG_STR_FILE_BROWSER, luaL_optstring( L, 1, "A" ), "A", return_string_selected);
1219     // Yield the script so that the action stack will process the AS_FILE_BROWSER action
1220     return lua_yield(L, 0);
1221 }
1222 
1223 static int luaCB_textbox( lua_State* L ) {
1224     // Disconnect button input from script so buttons will work in the textbox
1225     camera_info.state.state_kbd_script_run = SCRIPT_STATE_INACTIVE;
1226     // Switch to textbox gui mode. Text box prompt should be passed as param.
1227     int rv = libtextbox->textbox_init((int)luaL_optstring( L, 1, "Text box" ),   //title
1228         (int)luaL_optstring( L, 2, "Enter text" ), //message
1229         luaL_optstring( L, 3, ""  ),               //default string
1230         luaL_optnumber( L, 4, 30),                 //max size of a text
1231         return_string_selected, 0);
1232     if (rv)
1233     {
1234         // Push textbox action onto stack - will loop doing nothing until textbox exits
1235         action_push_func(action_stack_AS_WAIT_MODULE);
1236     }
1237     else
1238         return_string_selected(0);
1239 
1240     // Yield the script so that the action stack will process the AS_TEXTBOX action
1241     return lua_yield(L, 0);
1242 }
1243 
1244 // begin lua draw fuctions
1245 static int luaCB_draw_pixel( lua_State* L ) {
1246   coord x1=luaL_checknumber(L,1);
1247   coord y1=luaL_checknumber(L,2);
1248   color cl=get_script_color(luaL_checknumber(L,3));
1249   draw_pixel(x1,y1,cl);
1250   return 0;
1251 }
1252 
1253 static int luaCB_draw_line( lua_State* L ) {
1254   coord x1=luaL_checknumber(L,1);
1255   coord y1=luaL_checknumber(L,2);
1256   coord x2=luaL_checknumber(L,3);
1257   coord y2=luaL_checknumber(L,4);
1258   color cl=get_script_color(luaL_checknumber(L,5));
1259   draw_line(x1,y1,x2,y2,cl);
1260   return 0;
1261 }
1262 
1263 static int luaCB_draw_rect( lua_State* L ) {
1264   coord x1=luaL_checknumber(L,1);
1265   coord y1=luaL_checknumber(L,2);
1266   coord x2=luaL_checknumber(L,3);
1267   coord y2=luaL_checknumber(L,4);
1268   color cl=get_script_color(luaL_checknumber(L,5));
1269   int   th=luaL_optnumber(L,6,1) & RECT_BORDER_MASK;
1270   draw_rectangle(x1,y1,x2,y2,MAKE_COLOR(cl,cl),th);
1271   return 0;
1272 }
1273 
1274 static int luaCB_draw_rect_filled( lua_State* L ) {
1275   coord x1 =luaL_checknumber(L,1);
1276   coord y1 =luaL_checknumber(L,2);
1277   coord x2 =luaL_checknumber(L,3);
1278   coord y2 =luaL_checknumber(L,4);
1279   color clf=get_script_color(luaL_checknumber(L,5));
1280   color clb=get_script_color(luaL_checknumber(L,6));
1281   int   th =luaL_optnumber(L,7,1) & RECT_BORDER_MASK;
1282   draw_rectangle(x1,y1,x2,y2,MAKE_COLOR(clb,clf),th|DRAW_FILLED);
1283   return 0;
1284 }
1285 
1286 static int luaCB_draw_ellipse( lua_State* L ) {
1287   coord x1=luaL_checknumber(L,1);
1288   coord y1=luaL_checknumber(L,2);
1289   coord a=luaL_checknumber(L,3);
1290   coord b=luaL_checknumber(L,4);
1291   color cl=get_script_color(luaL_checknumber(L,5));
1292   draw_ellipse(x1,y1,a,b,cl,0);
1293   return 0;
1294 }
1295 
1296 static int luaCB_draw_ellipse_filled( lua_State* L ) {
1297   coord x1=luaL_checknumber(L,1);
1298   coord y1=luaL_checknumber(L,2);
1299   coord a=luaL_checknumber(L,3);
1300   coord b=luaL_checknumber(L,4);
1301   color cl=get_script_color(luaL_checknumber(L,5));
1302   draw_ellipse(x1,y1,a,b,cl,DRAW_FILLED);
1303   return 0;
1304 }
1305 
1306 static int luaCB_draw_string( lua_State* L )
1307 {
1308   coord x1 = luaL_checknumber(L,1);
1309   coord y1 = luaL_checknumber(L,2);
1310   const char *t = luaL_checkstring( L, 3 );
1311   color clf = get_script_color(luaL_checknumber(L,4));
1312   color clb = get_script_color(luaL_checknumber(L,5));
1313   int xsize = luaL_optnumber(L,6,1);
1314   int ysize = luaL_optnumber(L,7,xsize);
1315   
1316   if ((xsize <= 1) && (ysize <= 1))
1317     draw_string(x1, y1, t, MAKE_COLOR(clb,clf));
1318   else
1319     draw_string_scaled(x1, y1, t, MAKE_COLOR(clb,clf), xsize, ysize);
1320   
1321   return 0;
1322 }
1323 
1324 static int luaCB_draw_clear( lua_State* L ) {
1325   draw_restore();
1326   return 0;
1327 }
1328 // end lua draw functions
1329 
1330 // bitmap dimensions, size matches coordinates of draw functions
1331 static int luaCB_get_gui_screen_width( lua_State* L )
1332 {
1333     lua_pushnumber( L, camera_screen.width );
1334     return 1;
1335 }
1336 
1337 static int luaCB_get_gui_screen_height( lua_State* L )
1338 {
1339     lua_pushnumber( L, camera_screen.height );
1340     return 1;
1341 }
1342 
1343 static int luaCB_autostarted( lua_State* L )
1344 {
1345   lua_pushboolean( L, camera_info.state.auto_started );
1346   return 1;
1347 }
1348 
1349 static int luaCB_get_autostart( lua_State* L )
1350 {
1351   lua_pushnumber( L, conf.script_startup );
1352   return 1;
1353 }
1354 
1355 static int luaCB_set_autostart( lua_State* L )
1356 {
1357   int to;
1358   to = luaL_checknumber( L, 1 );
1359   if ( to >= 0 && to <= 3 ) conf.script_startup = to;
1360   conf_save();
1361   return 0;
1362 }
1363 
1364 static int luaCB_get_usb_power( lua_State* L )
1365 {
1366   lua_pushnumber( L, get_usb_power(luaL_optnumber( L, 1, 0 )) );
1367   return 1;
1368 }
1369 
1370 // enable USB High Perfomance timer
1371 static int luaCB_set_remote_timing( lua_State* L )
1372 {
1373   int val= on_off_value_from_lua_arg(L,1);
1374   if (val > 0 )
1375      lua_pushboolean(L,start_usb_HPtimer(val));
1376   else
1377      lua_pushboolean(L,stop_usb_HPtimer());
1378   return 1;
1379 }
1380 
1381 // enable shared USB port between ptp and precision sync
1382 static int luaCB_usb_force_active( lua_State* L )
1383 {
1384   lua_pushboolean(L,force_usb_state(on_off_value_from_lua_arg(L,1)));
1385   return 1;
1386 }
1387 
1388 // set next shot to wait for USB sync ( 5V - 0V transition )
1389 static int luaCB_usb_sync_wait( lua_State* L )
1390 {
1391   usb_sync_wait_flag = on_off_value_from_lua_arg(L,1);
1392   return 0;
1393 }
1394 
1395 static int luaCB_enter_alt( lua_State* L )
1396 {
1397   enter_alt();
1398   // if alt explicitly changed by script, set as 'saved' state
1399   if(lua_script_is_ptp) {
1400       ptp_saved_alt_state = 1;
1401   }
1402   return 0;
1403 }
1404 
1405 static int luaCB_exit_alt( lua_State* L )
1406 {
1407   exit_alt();
1408   // if alt explicitly changed by script, set as 'saved' state
1409   if(lua_script_is_ptp) {
1410       ptp_saved_alt_state = 0;
1411   }
1412   return 0;
1413 }
1414 
1415 static int luaCB_get_alt_mode( lua_State* L )
1416 {
1417     lua_pushboolean(L, (camera_info.state.gui_mode != 0));
1418     return 1 ;
1419 }
1420 
1421 // optional parameter is 0 for soft shutdown (default) or 1 for hard/immediate
1422 static int luaCB_shut_down( lua_State* L )
1423 {
1424   if ( luaL_optnumber(L,1,0) == 1 )
1425   {
1426     shutdown();
1427   } else {
1428   camera_shutdown_in_a_second();
1429   }
1430   return 0;
1431 }
1432 
1433 static int luaCB_print_screen( lua_State* L )
1434 {
1435     script_print_screen_statement( on_off_value_from_lua_arg( L, 1 ) );
1436     return 0;
1437 }
1438 
1439 static int luaCB_get_movie_status( lua_State* L )
1440 {
1441   lua_pushnumber( L, get_movie_status() );
1442   return 1;
1443 }
1444 
1445 static int luaCB_set_movie_status( lua_State* L )
1446 {
1447   set_movie_status( luaL_checknumber( L, 1 ) );
1448   return 0;
1449 }
1450 
1451 static int luaCB_get_video_button( lua_State* L )
1452 {
1453   lua_pushboolean( L, camera_info.cam_has_video_button );
1454   return 1;
1455 }
1456 
1457 static int luaCB_get_video_recording( lua_State* L )
1458 {
1459   lua_pushboolean( L, is_video_recording() );
1460   return 1;
1461 }
1462 
1463 static int luaCB_get_drive_mode( lua_State* L )
1464 {
1465   lua_pushnumber( L, shooting_get_drive_mode() );
1466   return 1;
1467 }
1468 
1469 static int luaCB_get_focus_mode( lua_State* L )
1470 {
1471   lua_pushnumber( L, shooting_get_real_focus_mode() );
1472   return 1;
1473 }
1474 
1475 static int luaCB_get_focus_state( lua_State* L )
1476 {
1477   lua_pushnumber( L, shooting_get_focus_state() );
1478   return 1;
1479 }
1480 
1481 static int luaCB_get_focus_ok( lua_State* L )
1482 {
1483   lua_pushboolean( L, shooting_get_focus_ok() );
1484   return 1;
1485 }
1486 
1487 static int luaCB_get_flash_mode( lua_State* L )
1488 {
1489   lua_pushnumber( L, shooting_get_flash_mode() );
1490   return 1;
1491 }
1492 
1493 static int luaCB_get_shooting( lua_State* L )
1494 {
1495   lua_pushboolean( L, shooting_in_progress() );
1496   return 1;
1497 }
1498 
1499 static int luaCB_get_flash_ready( lua_State* L )
1500 {
1501   lua_pushboolean( L, shooting_is_flash() );
1502   return 1;
1503 }
1504 
1505 static int luaCB_get_IS_mode( lua_State* L )
1506 {
1507   lua_pushnumber( L, shooting_get_is_mode() );
1508   return 1;
1509 }
1510 
1511 static int luaCB_get_orientation_sensor( lua_State* L )
1512 {
1513   lua_pushnumber( L, shooting_get_prop(camera_info.props.orientation_sensor) );
1514   return 1;
1515 }
1516 
1517 static int luaCB_get_zoom_steps( lua_State* L )
1518 {
1519   lua_pushnumber( L, zoom_points );
1520   return 1;
1521 }
1522 
1523 static int luaCB_get_nd_present( lua_State* L )
1524 {
1525   int to;
1526   if (camera_info.cam_has_nd_filter == 0)
1527   {
1528     to = 0;
1529   }
1530   else
1531   {
1532     if (camera_info.cam_has_iris_diaphragm == 0)
1533       to = 1;
1534     else
1535       to = 2;
1536   }
1537   lua_pushnumber( L, to );
1538   return 1;
1539 }
1540 
1541 static int luaCB_get_propset( lua_State* L )
1542 {
1543   lua_pushnumber( L, camera_info.props.propset );
1544   return 1;
1545 }
1546 
1547 static int luaCB_get_ev( lua_State* L )
1548 {
1549   lua_pushnumber( L, shooting_get_ev_correction1() );
1550   return 1;
1551 }
1552 
1553 static int luaCB_set_ev( lua_State* L )
1554 {
1555   int to;
1556   to = luaL_checknumber( L, 1 );
1557   shooting_set_prop(camera_info.props.ev_correction_1, to);
1558   shooting_set_prop(camera_info.props.ev_correction_2, to);
1559   return 0;
1560 }
1561 
1562 static int luaCB_get_histo_range( lua_State* L )
1563 {
1564   int from = (luaL_checknumber(L,1));
1565   int to = (luaL_checknumber(L,2));
1566   lua_pushnumber( L, libshothisto->shot_histogram_get_range(from, to) );
1567   return 1;
1568 }
1569 
1570 static int luaCB_shot_histo_enable( lua_State* L )
1571 {
1572   libshothisto->shot_histogram_set(on_off_value_from_lua_arg( L, 1 ));
1573   return 0;
1574 }
1575 
1576 static int luaCB_shot_histo_write_to_file( lua_State* L )
1577 {
1578     libshothisto->write_to_file();
1579     return 0;
1580 }
1581 
1582 /*
1583 histogram,total=get_live_histo()
1584 returns a histogram of Y values from the viewport buffer (downsampled by HISTO_STEP_SIZE)
1585 histogram[Y value] = count, so it is zero based unlike a normal lua array
1586 total is the total number of pixels, may vary depending on viewport size
1587 */
1588 static int luaCB_get_live_histo( lua_State* L )
1589 {
1590   unsigned short *h = malloc(256*sizeof(short));
1591   if(!h) {
1592       return luaL_error(L,"malloc fail");
1593   }
1594   int total=live_histogram_read_y(h);
1595   lua_createtable(L, 0, 256);
1596   int i;
1597   for(i=0;i<256;i++) {
1598     lua_pushnumber(L,h[i]);
1599     lua_rawseti(L,-2,i);
1600   }
1601   free(h);
1602   lua_pushnumber(L,total);
1603   return 2;
1604 }
1605 
1606 static int luaCB_play_sound( lua_State* L )
1607 {
1608   play_sound(luaL_checknumber( L, 1 ));
1609   return 0;
1610 }
1611 
1612 static int luaCB_get_temperature( lua_State* L )
1613 {
1614   int which = (luaL_checknumber( L, 1 ));
1615   int temp = -100; // do something insane if users passes bad value
1616   switch (which)
1617   {
1618     case 0:
1619       temp = get_optical_temp(); 
1620       break;
1621     case 1:
1622       temp = get_ccd_temp(); 
1623       break;
1624     case 2:
1625       temp = get_battery_temp();
1626       break;
1627   }
1628   lua_pushnumber( L, temp );
1629   return 1;
1630 }
1631 
1632 static int luaCB_get_time( lua_State* L )
1633 {
1634   int r = -1;
1635   static struct tm *ttm;
1636   ttm = get_localtime();
1637   const char *t = luaL_checkstring( L, 1 );
1638   if (strncmp("s", t, 1)==0) r = ( L, ttm->tm_sec );
1639   else if (strncmp("m", t, 1)==0) r = ( L, ttm->tm_min );
1640   else if (strncmp("h", t, 1)==0) r = ( L, ttm->tm_hour );
1641   else if (strncmp("D", t, 1)==0) r = ( L, ttm->tm_mday );
1642   else if (strncmp("M", t, 1)==0) r = ( L, ttm->tm_mon+1 );
1643   else if (strncmp("Y", t, 1)==0) r = ( L, 1900+ttm->tm_year );
1644   lua_pushnumber( L, r );
1645   return 1;
1646 }
1647 /*
1648   val=peek(address[,size])
1649   return the value found at address in memory, or nil if address or size is invalid
1650   size is optional 1=byte 2=halfword 4=word. defaults is 4
1651 */
1652 static int luaCB_peek( lua_State* L )
1653 {
1654   unsigned addr = luaL_checknumber(L,1);
1655   unsigned size = luaL_optnumber(L, 2, 4);
1656   switch(size) {
1657     case 1: 
1658       lua_pushnumber( L, *(unsigned char *)(addr) );
1659     break;
1660     case 2:
1661       if (addr & 0x1) {
1662         lua_pushnil(L);
1663       }
1664       else {
1665         lua_pushnumber( L, *(unsigned short *)(addr) );
1666       }
1667     break;
1668     case 4:
1669       if (addr & 0x3) {
1670         lua_pushnil(L);
1671       }
1672       else {
1673         lua_pushnumber( L, *(unsigned *)(addr) );
1674       }
1675     break;
1676     default:
1677       lua_pushnil(L);
1678 
1679   }
1680   return 1;
1681 }
1682 
1683 /*
1684   status=poke(address,value[,size])
1685   writes value to address in memory
1686   size is optional 1=byte 2=halfword 4=word. defaults is 4
1687   returns true, or nil if address or size is invalid
1688 */
1689 static int luaCB_poke( lua_State* L )
1690 {
1691   unsigned addr = luaL_checknumber(L,1);
1692   unsigned val = luaL_checknumber(L,2);
1693   unsigned size = luaL_optnumber(L, 3, 4);
1694   int status = 0;
1695   switch(size) {
1696     case 1: 
1697         *(unsigned char *)(addr) = (unsigned char)val;
1698         status=1;
1699     break;
1700     case 2:
1701       if (!(addr & 0x1)) {
1702         *(unsigned short *)(addr) = (unsigned short)val;
1703         status=1;
1704       }
1705     break;
1706     case 4:
1707       if (!(addr & 0x3)) {
1708         *(unsigned *)(addr) = val;
1709         status=1;
1710       }
1711     break;
1712   }
1713   if(status) {
1714     lua_pushboolean(L,1);
1715   }
1716   else {
1717     lua_pushnil(L);
1718   }
1719   return 1;
1720 }
1721 
1722 static int luaCB_bitand( lua_State* L )
1723 {
1724   int v1 = (luaL_checknumber(L,1));
1725   int v2 = (luaL_checknumber(L,2));
1726   lua_pushnumber( L, v1 & v2 );
1727   return 1;
1728 }
1729 
1730 static int luaCB_bitor( lua_State* L )
1731 {
1732   int v1 = (luaL_checknumber(L,1));
1733   int v2 = (luaL_checknumber(L,2));
1734   lua_pushnumber( L, v1 | v2 );
1735   return 1;
1736 }
1737 
1738 static int luaCB_bitxor( lua_State* L )
1739 {
1740   int v1 = (luaL_checknumber(L,1));
1741   int v2 = (luaL_checknumber(L,2));
1742   lua_pushnumber( L, v1 ^ v2 );
1743   return 1;
1744 }
1745 
1746 static int luaCB_bitshl( lua_State* L )
1747 {
1748   int val = (luaL_checknumber(L,1));
1749   unsigned shift = (luaL_checknumber(L,2));
1750   lua_pushnumber( L, val << shift );
1751   return 1;
1752 }
1753 
1754 static int luaCB_bitshri( lua_State* L )
1755 {
1756   int val = (luaL_checknumber(L,1));
1757   unsigned shift = (luaL_checknumber(L,2));
1758   lua_pushnumber( L, val >> shift );
1759   return 1;
1760 }
1761 
1762 static int luaCB_bitshru( lua_State* L )
1763 {
1764   unsigned val = (luaL_checknumber(L,1));
1765   unsigned shift = (luaL_checknumber(L,2));
1766   lua_pushnumber( L, val >> shift );
1767   return 1;
1768 }
1769 
1770 static int luaCB_bitnot( lua_State* L )
1771 {
1772   unsigned val = (luaL_checknumber(L,1));
1773   lua_pushnumber( L, ~val );
1774   return 1;
1775 }
1776 
1777 void set_string_field(lua_State* L, const char *key, const char *val)
1778 {
1779   lua_pushstring(L, val);
1780   lua_setfield(L, -2, key);
1781 }
1782 
1783 void set_number_field(lua_State* L, const char *key, int val)
1784 {
1785   lua_pushnumber(L, val);
1786   lua_setfield(L, -2, key);
1787 }
1788 
1789 static int luaCB_get_buildinfo( lua_State* L )
1790 {
1791   lua_createtable(L, 0, 9);
1792   set_string_field( L,"platform", camera_info.platform );
1793   set_string_field( L,"platsub", camera_info.platformsub );
1794   set_string_field( L,"version", camera_info.chdk_ver );
1795   set_string_field( L,"build_number", camera_info.build_number );
1796   set_string_field( L,"build_revision", camera_info.build_svnrev );
1797   set_string_field( L,"build_date", camera_info.build_date );
1798   set_string_field( L,"build_time", camera_info.build_time );
1799   set_string_field( L,"os", camera_info.os );
1800   set_number_field( L,"platformid", conf.platformid );
1801   return 1;
1802 }
1803 
1804 static int luaCB_get_mode( lua_State* L )
1805 {
1806   lua_pushboolean( L, !camera_info.state.mode_play );
1807   lua_pushboolean( L, camera_info.state.mode_video );
1808   lua_pushnumber( L, camera_info.state.mode );
1809   return 3;
1810 }
1811 
1812 // TODO sanity check file ?
1813 static int luaCB_set_raw_develop( lua_State* L )
1814 {
1815   raw_prepare_develop(luaL_optstring( L, 1, NULL ), 0);
1816   return 0;
1817 }
1818 
1819 static int luaCB_raw_merge_start( lua_State* L )
1820 {
1821     int op = luaL_checknumber(L,1);
1822     if ((op == RAW_OPERATION_SUM || op == RAW_OPERATION_AVERAGE))
1823     {
1824         lua_pushboolean(L, librawop->raw_merge_start(op));   
1825         return 1;
1826     }
1827     else {
1828         return luaL_argerror(L,1,"invalid raw merge op");
1829     }
1830 }
1831 
1832 // TODO sanity check file ? Get it from C
1833 static int luaCB_raw_merge_add_file( lua_State* L )
1834 {
1835     lua_pushboolean(L, librawop->raw_merge_add_file(luaL_checkstring( L, 1 )));
1836     return 1;
1837 }
1838 
1839 static int luaCB_raw_merge_end( lua_State* L )
1840 {
1841     librawop->raw_merge_end();
1842     return 0;
1843 }
1844 
1845 // Enable/disable LCD back light (input argument 1/0)
1846 static int luaCB_set_backlight( lua_State* L )
1847 {
1848   int val = on_off_value_from_lua_arg(L,1);
1849 
1850   if (val > 0) TurnOnBackLight();
1851   else TurnOffBackLight();
1852   return 0;
1853 }
1854 
1855 // Enable/disable LCD display (input argument 1/0)
1856 static int luaCB_set_lcd_display( lua_State* L )
1857 {
1858   int val = on_off_value_from_lua_arg(L,1);
1859 
1860   if (val > 0) TurnOnDisplay();
1861   else TurnOffDisplay();
1862   return 0;
1863 }
1864 
1865 // Enable/disable CHDK <ALT> & scriptname OSD items (input argument 1/0)
1866 static int luaCB_set_draw_title_line( lua_State* L )
1867 {
1868   camera_info.state.osd_title_line= on_off_value_from_lua_arg(L,1);
1869   return 0;
1870 }
1871 
1872 // get CHDK <ALT> & scriptname OSD display state (input argument 1/0)
1873 static int luaCB_get_draw_title_line( lua_State* L )
1874 {
1875    lua_pushboolean( L, camera_info.state.osd_title_line  );
1876    return 1;
1877 }
1878 
1879 // get the string or number passed in index and return it as an event id
1880 static unsigned levent_id_from_lua_arg( lua_State* L, int index)
1881 {
1882   unsigned event_id;
1883   if (lua_type(L, index) == LUA_TSTRING) {
1884     const char *ev_name = lua_tostring(L, index);
1885     event_id = levent_id_for_name(ev_name);
1886     if (event_id == 0) {
1887         return luaL_error( L, "bad event name '%s'", ev_name );
1888     }
1889   }
1890   // could check here if it is in the table, but even valid ones can crash
1891   // so we avoid searching the table if given a number
1892   else if (lua_type(L,index) == LUA_TNUMBER){
1893     event_id = lua_tonumber(L,index);
1894   }
1895   else {
1896     return luaL_error( L, "expected event name or id" );
1897   }
1898   return event_id;
1899 }
1900 
1901 
1902 /*
1903   return the index of an event, given it's name or event id
1904 */
1905 static unsigned levent_index_from_id_lua_arg( lua_State* L, int index )
1906 {
1907   if (lua_type(L, index) == LUA_TSTRING) {
1908     return levent_index_for_name(lua_tostring(L, index));
1909   }
1910   else if (lua_type(L,index) == LUA_TNUMBER){
1911     return levent_index_for_id(lua_tonumber(L,index));
1912   }
1913   else {
1914     return luaL_error( L, "expected string or number" );
1915   }
1916 }
1917 
1918 /*
1919   name,id,param = get_levent_def(event)
1920   event is an event id (number) or name (string)
1921   returns nil if event is not found
1922 */
1923 static int luaCB_get_levent_def( lua_State* L )
1924 {
1925   unsigned event_index = levent_index_from_id_lua_arg(L,1);
1926   if (event_index == LEVENT_INVALID_INDEX) {
1927     lua_pushnil(L);
1928     return 1;
1929   }
1930   lua_pushstring(L, levent_table[event_index].name);
1931   lua_pushnumber(L, levent_table[event_index].id);
1932   lua_pushnumber(L, levent_table[event_index].param);
1933   return 3;
1934 }
1935 
1936 /*
1937   index=get_levent_index(event)
1938   event is an event id (number) or name (string)
1939   returns index or nil if not found
1940 */
1941 static int luaCB_get_levent_index( lua_State* L )
1942 {
1943   unsigned event_index = levent_index_from_id_lua_arg(L,1);
1944   if (event_index == LEVENT_INVALID_INDEX) {
1945     lua_pushnil(L);
1946   }
1947   else {
1948     lua_pushnumber(L, event_index);
1949   }
1950   return 1;
1951 }
1952 
1953 /*
1954   name,id,param = get_levent_def_by_index(event_index)
1955   event_index is number index into the event table
1956   returns nil if event is not found
1957 */
1958 static int luaCB_get_levent_def_by_index( lua_State* L )
1959 {
1960   unsigned i = luaL_checknumber(L,1);
1961   if(i >= levent_count()) {
1962     lua_pushnil(L);
1963     return 1;
1964   }
1965   lua_pushstring(L, levent_table[i].name);
1966   lua_pushnumber(L, levent_table[i].id);
1967   lua_pushnumber(L, levent_table[i].param);
1968   return 3;
1969 }
1970 
1971 /*
1972   post_levent_*(event[,unk])
1973   post the event with PostLogicalEventToUI or PostLogicaEventForNotPowerType
1974   This sends the event. The difference between functions isn't clear.
1975   event is an event id (number) or name (string).
1976   unk is an optional number whose meaning is unknown, defaults to zero. 
1977     Based on code, other values would probably be a pointer.
1978     This is NOT the 3rd item in the event table.
1979 */
1980 static int luaCB_post_levent_to_ui( lua_State* L )
1981 {
1982   unsigned event_id,arg;
1983 
1984   event_id = levent_id_from_lua_arg(L,1);
1985   arg = luaL_optnumber(L, 2, 0);
1986   PostLogicalEventToUI(event_id,arg);
1987   return 0;
1988 }
1989 
1990 static int luaCB_post_levent_for_npt( lua_State* L )
1991 {
1992   unsigned event_id,arg;
1993 
1994   event_id = levent_id_from_lua_arg(L,1);
1995   arg = luaL_optnumber(L, 2, 0);
1996   PostLogicalEventForNotPowerType(event_id,arg);
1997   return 0;
1998 }
1999 
2000 /*
2001   set_levent_active(event,state)
2002   event is an event id (number) or name (string)
2003   state is a numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
2004   exact meaning is unknown, but it has something to do with the delivery of the specified event.
2005 */
2006 static int luaCB_set_levent_active( lua_State* L )
2007 {
2008   unsigned event_id;
2009   unsigned state;
2010 
2011   event_id = levent_id_from_lua_arg(L,1);
2012   state = on_off_value_from_lua_arg(L,2);
2013   SetLogicalEventActive(event_id,state);
2014   return 0;
2015 }
2016 
2017 /*
2018   set_levent_script_mode(state)
2019   state is numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
2020   exact meaning is unknown, but it has something to do with the behavior of events and/or SetLogicalEventActive.
2021 */
2022 static int luaCB_set_levent_script_mode( lua_State* L )
2023 {
2024   SetScriptMode(on_off_value_from_lua_arg(L,1));
2025   return 0;
2026 }
2027 
2028 /* 
2029   result=set_capture_mode_canon(value)
2030   where value is a valid PROPCASE_SHOOTING_MODE value for the current camera
2031   result is true if the camera is in rec mode
2032 */
2033 static int luaCB_set_capture_mode_canon( lua_State* L )
2034 {
2035   int modenum = luaL_checknumber(L,1);
2036   // if the value as negative, assume it is a mistakenly sign extended PROPCASE_SHOOTING_MODE value
2037   if(modenum < 0) 
2038     modenum &= 0xFFFF;
2039   lua_pushboolean( L, shooting_set_mode_canon(modenum) );
2040   return 1;
2041 }
2042 
2043 /*
2044  result=set_capture_mode(modenum)
2045  where modenum is a valid CHDK modemap value
2046  result is true if modenum is a valid modemap value, otherwise false
2047 */
2048 static int luaCB_set_capture_mode( lua_State* L )
2049 {
2050   int modenum = luaL_checknumber(L,1);
2051   lua_pushboolean( L, shooting_set_mode_chdk(modenum) );
2052   return 1;
2053 }
2054 
2055 /*
2056  result=is_capture_mode_valid(modenum)
2057  where modenum is a valid CHDK modemap value
2058  result is true if modenum is a valid modemap value, otherwise false
2059 */
2060 static int luaCB_is_capture_mode_valid( lua_State* L )
2061 {
2062   int modenum = luaL_checknumber(L,1);
2063   lua_pushboolean( L, shooting_mode_chdk2canon(modenum) != -1 );
2064   return 1;
2065 }
2066 
2067 /* 
2068   set_record(state)
2069   if state is 0 (or false) the camera is set to play mode. If 1 or true, the camera is set to record mode.
2070   NOTE: this only begins the mode change. Script should wait until get_mode() reflects the change,
2071   before doing anything that requires the new mode. e.g.
2072   set_record(true)
2073   while not get_mode() do
2074     sleep(10)
2075   end
2076   uses switch_mode_usb if required
2077 */
2078 static int luaCB_set_record( lua_State* L )
2079 {
2080   shooting_set_playrec_mode(on_off_value_from_lua_arg(L,1));
2081   return 0;
2082 }
2083 
2084 // switch mode (0 = playback, 1 = record)
2085 // only for when USB is connected
2086 static int luaCB_switch_mode_usb( lua_State* L )
2087 {
2088   switch_mode_usb(on_off_value_from_lua_arg(L,1));
2089   return 0;
2090 }
2091  
2092 /*
2093 pack the lua args into a buffer to pass to the native code calling functions 
2094 currently only handles strings/numbers
2095 start is the stack index of the first arg
2096 */
2097 static int pack_native_args( lua_State* L, unsigned start, unsigned *argbuf)
2098 {
2099   unsigned i;
2100   unsigned end = lua_gettop(L);
2101 
2102   for(i = start; i <= end; i++,argbuf++) {
2103     if (lua_type(L, i) == LUA_TSTRING) {
2104         *argbuf=(unsigned)lua_tostring( L, i);
2105     }
2106     else if (lua_type(L, i) == LUA_TNUMBER) {
2107         *argbuf=lua_tonumber( L, i);
2108     }
2109     else {
2110       return 0;
2111     }
2112   }
2113   return 1;
2114 }
2115 
2116 /*
2117 Native function call interface. Can be used to call canon eventprocs or arbitrary
2118 pointers.
2119 
2120 NOTE: this is preliminary, interface may change in later versions!
2121 All arguments must be strings or numbers.
2122 If the function expects to modify it's arguments via a pointer,
2123 then you must provide a number that is a valid pointer. 
2124 
2125 You can use the "AllocateMemory" eventproc to obtain buffers.
2126 
2127 If the function tries to write to a string passed from lua, Bad Things may happen.
2128 
2129 This is potentially dangerous, functions exist which can destroy the onboard firmware.
2130 */
2131 
2132 /*
2133 result=call_func_ptr(ptr,...)
2134 ptr: address of a valid ARM or Thumb function, which uses the normal C calling convention.
2135 result: R0 value after the call returns
2136 */
2137 static int luaCB_call_func_ptr( lua_State* L)
2138 {
2139     if (conf.script_allow_lua_native_calls)
2140     {
2141         unsigned *argbuf=NULL;
2142         unsigned n_args = lua_gettop(L)-1;
2143         void *fptr;
2144 
2145         fptr=(void *)luaL_checknumber( L, 1 );
2146 
2147         if (n_args)
2148         {
2149             argbuf=malloc(n_args * 4);
2150             if(!argbuf)
2151             {
2152                 return luaL_error( L, "malloc fail" );
2153             }
2154             if(!pack_native_args(L, 2, argbuf))
2155             {
2156                 free(argbuf);
2157                 return luaL_error( L, "expected string or number" );
2158             }
2159         }
2160           
2161         lua_pushnumber( L, call_func_ptr(fptr, argbuf, n_args) );
2162         free(argbuf);
2163         return 1;
2164     }
2165     return luaL_error( L, "native calls disabled" );
2166 }
2167 
2168 /* 
2169 Call an event procedure
2170 
2171 result=call_event_proc("EventprocName",...)
2172 result is the value returned by ExecuteEventProcedure, which is -1 if the eventproc is not found, 
2173 or the eventproc return value (which could also be -1)
2174 NOTE:
2175 Many eventprocs are not registered by default, but can be loaded by calling another event proc
2176 Some useful ones are
2177 SystemEventInit
2178     includes AllocateMemory, FreeMemory, sprintf, memcpy, Fut functions, log ...
2179 UI_RegistDebugEventProc
2180     includes capture mode functions, PTM_ functions and much more 
2181 RegisterProductTestEvent
2182     includes PT_ functions
2183 
2184 Others:
2185 RegisterShootSeqEvent
2186 RegisterNRTableEvent
2187 */
2188 
2189 // grab from lowlevel
2190 extern unsigned _ExecuteEventProcedure(const char *name,...);
2191 static int luaCB_call_event_proc( lua_State* L )
2192 {
2193     if (conf.script_allow_lua_native_calls)
2194     {
2195         const char *evpname;
2196         unsigned *argbuf;
2197         unsigned n_args = lua_gettop(L);
2198 
2199         evpname=luaL_checkstring( L, 1 );
2200 
2201         argbuf=malloc(n_args * 4);
2202         if (!argbuf)
2203         {
2204             return luaL_error( L, "malloc fail" );
2205         }
2206 
2207         // event proc name is first arg
2208         *argbuf = (unsigned)evpname;
2209   
2210         if(!pack_native_args(L,2,argbuf+1))
2211         {
2212             free(argbuf);
2213             return luaL_error( L, "expected string or number" );
2214         }
2215   
2216         lua_pushnumber( L, call_func_ptr(_ExecuteEventProcedure,argbuf,n_args) );
2217         free(argbuf);
2218         return 1;
2219     }
2220     return luaL_error( L, "native calls disabled" );
2221 }
2222 
2223 /*
2224 result = reboot(["filename"])
2225 returns false on failure, does not return on success
2226 see lib/armutil/reboot.c for details
2227 */
2228 static int luaCB_reboot( lua_State* L )
2229 {
2230     lua_pushboolean(L, reboot(luaL_optstring( L, 1, NULL )));
2231     return 1;
2232 }
2233 
2234 static int luaCB_get_config_value( lua_State* L ) {
2235     unsigned int argc = lua_gettop(L);
2236     unsigned int id, i;
2237     int ret = 1;
2238     tConfigVal configVal;
2239     
2240     if( argc>=1 ) {
2241         id = luaL_checknumber(L, 1);
2242         switch( conf_getValue(id, &configVal) ) {
2243             case CONF_VALUE:
2244                 lua_pushnumber(L, configVal.numb);
2245             break;
2246             case CONF_INT_PTR:
2247                 lua_createtable(L, 0, configVal.numb);
2248                 for( i=0; i<configVal.numb; i++ ) {
2249                     lua_pushinteger(L, configVal.pInt[i]);
2250                     lua_rawseti(L, -2, i+1);  //t[i+1]=configVal.pInt[i]
2251                 }
2252             break;
2253             case CONF_CHAR_PTR:
2254                 lua_pushstring(L, configVal.str);
2255             break;
2256             case CONF_OSD_POS:
2257                 lua_pushnumber(L, configVal.pos.x);
2258                 lua_pushnumber(L, configVal.pos.y); ret++;
2259             break;
2260             default:
2261                 if( argc>=2) { //Default
2262                     ret = argc-1;
2263                 } else {
2264                     lua_pushnil(L);
2265                 }
2266             break;
2267         }
2268     } else {
2269         lua_pushnil(L);
2270     }
2271     return ret;
2272 }
2273 
2274 static int luaCB_set_config_value( lua_State* L ) {
2275     unsigned int argc = lua_gettop(L);
2276     unsigned int id, i, j;
2277     tConfigVal configVal = {0,0,0,0};  //initialize isXXX
2278     
2279     if( argc>=2 ) {
2280         id = luaL_checknumber(L, 1);
2281         for( i=2; i<=argc; i++) {
2282             switch( lua_type(L, i) ) {
2283                 case LUA_TNUMBER:
2284                     if( !configVal.isNumb ) {
2285                         configVal.numb = luaL_checknumber(L, i);
2286                         configVal.isNumb++;
2287                     }
2288                     switch( configVal.isPos ) {
2289                         case 0: configVal.pos.x = luaL_checknumber(L, i); configVal.isPos++; break;
2290                         case 1: configVal.pos.y = luaL_checknumber(L, i); configVal.isPos++; break;
2291                     }
2292                 break;
2293                 case LUA_TSTRING:
2294                     if( !configVal.isStr ) {
2295                         configVal.str = (char*)luaL_checkstring(L, i);
2296                         configVal.isStr++;
2297                     }
2298                 break;
2299                 case LUA_TTABLE:
2300                     if( !configVal.isPInt ) {
2301                         configVal.numb = lua_objlen(L, i);
2302                         if( configVal.pInt ) {
2303                             free(configVal.pInt);
2304                             configVal.pInt = NULL;
2305                         }
2306                         configVal.pInt = malloc(configVal.numb*sizeof(int));
2307                         if( configVal.pInt ) {
2308                             for( j=1; j<=configVal.numb; j++) {
2309                                 lua_rawgeti(L, i, j);
2310                                 configVal.pInt[j-1] = lua_tointeger(L, -1);
2311                                 lua_pop(L, 1);
2312                             }
2313                         }
2314                         configVal.isPInt++;
2315                     }
2316                 break;
2317             }
2318         }
2319         lua_pushboolean(L, conf_setValue(id, configVal));
2320         if( configVal.pInt ) {
2321             free(configVal.pInt);
2322             configVal.pInt = NULL;
2323         }
2324     } else lua_pushboolean(L, 0);
2325     return 1;
2326 }
2327 
2328 static int luaCB_set_config_autosave( lua_State* L ) {
2329     conf_setAutosave(on_off_value_from_lua_arg(L, 1));
2330     return 0;
2331 }
2332 
2333 static int luaCB_save_config_file( lua_State* L ) {
2334     lua_pushboolean(L, save_config_file(luaL_checknumber(L, 1), luaL_optstring(L, 2, NULL)));
2335     return 1;
2336 }
2337 
2338 static int luaCB_load_config_file( lua_State* L ) {
2339     lua_pushboolean(L, load_config_file(luaL_checknumber(L, 1), luaL_optstring(L, 2, NULL)));
2340     return 1;
2341 }
2342 
2343 static int luaCB_set_file_attributes( lua_State* L ) {
2344     lua_pushnumber(L, SetFileAttributes(luaL_checkstring(L, 1), luaL_checknumber(L, 2)));
2345     return 1;
2346 }
2347 
2348 static int action_stack_AS_SCRIPT_READ_USB_MSG()
2349 {
2350     ptp_script_msg *msg = ptp_script_read_msg();
2351 
2352     if ((get_tick_count() >= action_top(2)) || msg)
2353     {
2354         if (msg && msg->data)
2355         {
2356             lua_pushlstring(Lt,msg->data,msg->size);
2357         }
2358         else
2359         {
2360             lua_pushnil(Lt);
2361         }
2362         action_pop_func(1);
2363         return 1;
2364     }
2365     return 0;
2366 }
2367 
2368 static int action_stack_AS_SCRIPT_WRITE_USB_MSG()
2369 {
2370     ptp_script_msg *msg = (ptp_script_msg *)action_top(2);
2371 
2372     int r = ptp_script_write_msg(msg);
2373 
2374     if ((get_tick_count() >= action_top(3)) || r)
2375     {
2376         lua_pushboolean(Lt,r);
2377         action_pop_func(2);
2378         return 1;
2379     }
2380     return 0;
2381 }
2382 
2383 /*
2384 msg = read_usb_msg([timeout])
2385 read a message from the CHDK ptp interface.
2386 Returns the next available message as a string, or nil if no messages are available
2387 If timeout is given and not zero, wait until a message is available or timeout expires
2388 */
2389 static int luaCB_read_usb_msg( lua_State* L )
2390 {
2391   int timeout = sleep_delay(luaL_optnumber(L,1,0));
2392   if (timeout > 0)
2393   {
2394     action_push(timeout);
2395     action_push_func(action_stack_AS_SCRIPT_READ_USB_MSG);
2396     return lua_yield( L, 0 );
2397   }
2398   ptp_script_msg *msg = ptp_script_read_msg();
2399   if(msg)
2400   {
2401     lua_pushlstring(L,msg->data,msg->size);
2402     free(msg);
2403     return 1;
2404   }
2405   lua_pushnil(L);
2406   return 1;
2407 }
2408 
2409 /*
2410 status = write_usb_msg(msg,[timeout])
2411 writes a message to the CHDK ptp interface
2412 msg may be nil, boolean, number, string or table (table has some restrictions, will be converted to string)
2413 returns true if the message was queued successfully, otherwise false
2414 if timeout is set and not zero, wait until message is written or timeout expires
2415 NOTE strings will not include a terminating NULL, must be handled by recipient
2416 */
2417 static int luaCB_write_usb_msg( lua_State* L )
2418 {
2419   ptp_script_msg *msg;
2420   int timeout = sleep_delay(luaL_optnumber(L,2,0));
2421   // TODO would it be better to either ignore this or return nil ?
2422   // a write_usb_msg(function_which_returns_no_value()) is an error in this case
2423   // replacing with nil might be more luaish
2424   if (lua_gettop(L) < 1)
2425   {
2426     return luaL_error(L,"missing argument");
2427   }
2428   msg=lua_create_usb_msg(L,1,PTP_CHDK_S_MSGTYPE_USER);
2429   // for user messages, trying to create a message from an incompatible type throws an error
2430   if (msg->subtype == PTP_CHDK_TYPE_UNSUPPORTED)
2431   {
2432     free(msg);
2433     return luaL_error(L,"unsupported type");
2434   }
2435   if (!msg)
2436   {
2437     return luaL_error(L,"failed to create message");
2438   }
2439   if (timeout)
2440   {
2441     action_push(timeout);
2442     action_push((int)msg);
2443     action_push_func(action_stack_AS_SCRIPT_WRITE_USB_MSG);
2444     return lua_yield( L, 0 );
2445   }
2446   lua_pushboolean(L,ptp_script_write_msg(msg)); 
2447   return 1;
2448 }
2449 
2450 /* helper for meminfo to set table field only if valid */
2451 static void set_meminfo_num( lua_State* L,const char *name, int val) {
2452     if(val != -1) {
2453         set_number_field( L, name, val );
2454     }
2455 }
2456 /*
2457 meminfo=get_meminfo([heapname])
2458 get camera memory information
2459 heapname="combined", "system", "aram" or "exmem" 
2460 if not given, combined is returned
2461 meminfo is false if the requested heapname isn't valid ("exmem" when exmem is not enabled, or unknown)
2462 otherwise, a table of the form
2463 meminfo = {
2464     name -- heapname, as above
2465     chdk_malloc -- bool, this is the heap used by CHDK for malloc
2466     chdk_start -- number, load address of CHDK
2467     chdk_size -- number, size of CHDK image
2468     -- all the following are numbers, will not be set if not available
2469     start_address
2470     end_address
2471     total_size
2472     allocated_size
2473     allocated_peak
2474     allocated_count
2475     free_size
2476     free_block_max_size
2477     free_block_count
2478 }
2479 NOTES
2480 * under vxworks and cameras without GetMemInfo only the only valid fields
2481   for the system heap will be those defined by chdk and free_block_max_size
2482 * the meaning of fields may not correspond exactly between exmem and system
2483 */
2484 static int luaCB_get_meminfo( lua_State* L ) {
2485     const char *heapname = luaL_optstring( L, 1, "combined" );
2486     cam_meminfo meminfo;
2487     if (strcmp(heapname,"combined") == 0) {
2488         GetCombinedMemInfo(&meminfo);
2489         meminfo.start_address=meminfo.end_address=-1; // not meaningful
2490     }
2491     else if (strcmp(heapname,"system") == 0)
2492     {
2493         GetMemInfo(&meminfo);
2494     }
2495     else if ((strcmp(heapname,"aram") == 0))
2496     {
2497         if(!GetARamInfo(&meminfo)) {
2498             lua_pushboolean(L,0);
2499             return 1;
2500         }
2501     }
2502     else if (strcmp(heapname,"exmem") == 0)
2503     {
2504         if(!GetExMemInfo(&meminfo)) {;
2505             lua_pushboolean(L,0);
2506             return 1;
2507         }
2508     }
2509     else
2510     {
2511         lua_pushboolean(L,0);
2512         return 1;
2513     }
2514     // adjust start and size, if CHDK is loaded at heap start
2515     if(meminfo.start_address == camera_info.text_start) {
2516         meminfo.start_address += camera_info.memisosize;
2517         meminfo.total_size -= camera_info.memisosize;
2518     }
2519     lua_createtable(L, 0, 13); // might not always use 13, but doesn't hurt
2520     set_string_field( L,"name", heapname );
2521     // CHDK allocates from all available heaps now
2522     lua_pushboolean( L, 1);
2523     lua_setfield(L, -2, "chdk_malloc");
2524     set_number_field( L, "chdk_start", camera_info.text_start);
2525     set_number_field( L, "chdk_size", camera_info.memisosize );
2526     set_meminfo_num( L, "start_address", meminfo.start_address );
2527     set_meminfo_num( L, "end_address", meminfo.end_address);
2528     set_meminfo_num( L, "total_size", meminfo.total_size);
2529     set_meminfo_num( L, "allocated_size", meminfo.allocated_size);
2530     set_meminfo_num( L, "allocated_peak", meminfo.allocated_peak);
2531     set_meminfo_num( L, "allocated_count", meminfo.allocated_count);
2532     set_meminfo_num( L, "free_size", meminfo.free_size);
2533     set_meminfo_num( L, "free_block_max_size", meminfo.free_block_max_size);
2534     set_meminfo_num( L, "free_block_count", meminfo.free_block_count);
2535     return 1;
2536 }
2537 
2538 /*
2539 set scheduling parameters
2540 old_max_count,old_max_ms=set_yield(max_count,max_ms)
2541 */
2542 static int luaCB_set_yield( lua_State* L )
2543 {
2544   lua_pushnumber(L,yield_max_count);
2545   lua_pushnumber(L,yield_max_ms);
2546   yield_max_count = luaL_optnumber(L,1,YIELD_MAX_COUNT_DEFAULT);
2547   yield_max_ms = luaL_optnumber(L,2,YIELD_MAX_MS_DEFAULT);
2548   return 2;
2549 }
2550 
2551 //static void register_func( lua_State* L, const char *name, void *func) {
2552 //  lua_pushcfunction( L, func );
2553 //  lua_setglobal( L, name );
2554 //}
2555 /*
2556 get remote capture supported types
2557 bitmask=get_usb_capture_support()
2558 */
2559 static int luaCB_get_usb_capture_support( lua_State* L )
2560 {
2561     lua_pushnumber(L,remotecap_get_target_support());
2562     return 1;
2563 }
2564 
2565 /*
2566 status=init_usb_capture(bitmask[,startline, numlines])
2567 bitmask = 0 clear usb capture mode
2568 
2569 lines only applies to raw
2570 startline defaults to 0
2571 numlines defaults to full buffer
2572 */
2573 static int luaCB_init_usb_capture( lua_State* L )
2574 {
2575     int what=luaL_checknumber(L, 1);
2576     int startline=luaL_optnumber(L, 2, 0);
2577     int numlines=luaL_optnumber(L, 3, 0);
2578     lua_pushboolean(L,remotecap_set_target(what,startline,numlines));
2579     return 1;
2580 }
2581 
2582 /*
2583 selected=get_usb_capture_target()
2584 selected = bitmask passed to init, or 0 if capture not configured or timed out/canceled
2585 */
2586 static int luaCB_get_usb_capture_target( lua_State* L )
2587 {
2588     lua_pushnumber(L,remotecap_get_target());
2589     return 1;
2590 }
2591 
2592 /*
2593 set_remotecap_timeout([timeout])
2594 timeout:
2595 number of milliseconds remote capture waits for data of each type to be downloaded
2596 <=0 or no value resets to the default value
2597 If any data type is not downloaded before the timeout expires, remote capture is canceled
2598 and none of the subsequent data types will be returned
2599 following a timeout, RemoteCaptureIsReady and RemoteCaptureGetData will behave as if
2600 remote capture were not initialized
2601 If the timeout expires while a transfer is in progress, an error will be generated
2602 and the data may be incomplete or corrupt
2603 */
2604 static int luaCB_set_usb_capture_timeout( lua_State* L )
2605 {
2606     remotecap_set_timeout(luaL_optnumber(L,1,0));
2607     return 0;
2608 }
2609 
2610 //------------------------------------------------------------------------------------------
2611 // APEX conversion functions
2612 
2613 static int luaCB_iso_to_sv96( lua_State* L )
2614 {
2615   lua_pushnumber(L, shooting_get_sv96_from_iso(luaL_checknumber(L, 1)));
2616   return 1;
2617 }
2618 
2619 static int luaCB_sv96_to_iso( lua_State* L )
2620 {
2621   lua_pushnumber(L, shooting_get_iso_from_sv96(luaL_checknumber(L, 1)));
2622   return 1;
2623 }
2624 
2625 static int luaCB_iso_real_to_market( lua_State* L )
2626 {
2627   lua_pushnumber(L, shooting_iso_real_to_market(luaL_checknumber(L, 1)));
2628   return 1;
2629 }
2630 
2631 static int luaCB_iso_market_to_real( lua_State* L )
2632 {
2633   lua_pushnumber(L, shooting_iso_market_to_real(luaL_checknumber(L, 1)));
2634   return 1;
2635 }
2636 
2637 static int luaCB_sv96_real_to_market( lua_State* L )
2638 {
2639   lua_pushnumber(L, shooting_sv96_real_to_market(luaL_checknumber(L, 1)));
2640   return 1;
2641 }
2642 
2643 static int luaCB_sv96_market_to_real( lua_State* L )
2644 {
2645   lua_pushnumber(L, shooting_sv96_market_to_real(luaL_checknumber(L, 1)));
2646   return 1;
2647 }
2648 
2649 static int luaCB_aperture_to_av96( lua_State* L )
2650 {
2651   lua_pushnumber(L, shooting_get_av96_from_aperture(luaL_checknumber(L, 1)));
2652   return 1;
2653 }
2654 
2655 static int luaCB_av96_to_aperture( lua_State* L )
2656 {
2657   lua_pushnumber(L, shooting_get_aperture_from_av96(luaL_checknumber(L, 1)));
2658   return 1;
2659 }
2660 
2661 static int luaCB_usec_to_tv96( lua_State* L )
2662 {
2663   lua_pushnumber(L, shooting_get_tv96_from_shutter_speed((float)luaL_checknumber(L, 1)/1000000.0));
2664   return 1;
2665 }
2666 
2667 static int luaCB_tv96_to_usec( lua_State* L )
2668 {
2669   lua_pushnumber(L, (int)(shooting_get_shutter_speed_from_tv96(luaL_checknumber(L, 1)) * 1000000.0 + 0.5));
2670   return 1;
2671 }
2672 
2673 static int luaCB_seconds_to_tv96( lua_State* L )
2674 {
2675   lua_pushnumber(L, shooting_get_tv96_from_shutter_speed((float)luaL_checknumber(L, 1)/(float)luaL_checknumber(L, 2)));
2676   return 1;
2677 }
2678 
2679 //------------------------------------------------------------------------------------------
2680 // Shoot hooks
2681 
2682 /*
2683 hook.set(timeout)
2684 cause hook to block shooting process until timeout or script issues hook.continue
2685 0 clears
2686 */
2687 static int luaCB_shoot_hook_set( lua_State* L )
2688 {
2689     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2690     script_shoot_hook_set(hook,luaL_checknumber(L, 1));
2691     return 0;
2692 }
2693 
2694 /*
2695 hook.is_ready()
2696 returns true if the hooked task is in the hook
2697 */
2698 static int luaCB_shoot_hook_is_ready( lua_State* L )
2699 {
2700     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2701     lua_pushboolean(L,script_shoot_hook_ready(hook));
2702     return 1;
2703 }
2704 
2705 /*
2706 hook.continue()
2707 allow the hooked task to leave the hook
2708 */
2709 static int luaCB_shoot_hook_continue( lua_State* L )
2710 {
2711     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2712     script_shoot_hook_continue(hook);
2713     return 0;
2714 }
2715 
2716 /*
2717 n=hook.count()
2718 return the number of times the hook has been reached since script start
2719 note: counts regardless of whether hook is enabled
2720 */
2721 static int luaCB_shoot_hook_count( lua_State* L )
2722 {
2723     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2724     lua_pushnumber(L,script_shoot_hook_count(hook));
2725     return 1;
2726 }
2727 
2728 //------------------------------------------------------------------------------------------
2729 
2730 #define FUNC( X ) { #X, luaCB_##X },
2731 static const luaL_Reg chdk_funcs[] = {
2732     FUNC(shoot)
2733     FUNC(sleep)
2734     FUNC(cls)
2735     FUNC(set_console_layout)
2736     FUNC(set_console_autoredraw)
2737     FUNC(console_redraw)
2738     FUNC(get_av96)
2739     FUNC(get_bv96)
2740     FUNC(get_day_seconds)
2741     FUNC(get_disk_size)
2742     FUNC(get_dofinfo)
2743     FUNC(get_free_disk_space)
2744     FUNC(get_focus)
2745     FUNC(get_iso_market)
2746     FUNC(get_iso_mode)
2747     FUNC(get_iso_real)
2748     FUNC(get_jpg_count)
2749     FUNC(get_prop)
2750     FUNC(get_prop_str)
2751     FUNC(get_raw_support)
2752     FUNC(get_raw_count)
2753     FUNC(get_raw_nr)
2754     FUNC(get_raw)
2755     FUNC(get_sv96)
2756     FUNC(get_tick_count)
2757     FUNC(get_tv96)
2758     FUNC(get_user_av_id)
2759     FUNC(get_user_av96)
2760     FUNC(get_user_tv_id)
2761     FUNC(get_user_tv96)
2762     FUNC(get_vbatt)
2763     FUNC(get_zoom)
2764     FUNC(get_exp_count)
2765     FUNC(get_image_dir)
2766     FUNC(get_flash_params_count)
2767     FUNC(get_parameter_data)
2768     FUNC(get_min_av96)
2769     FUNC(get_max_av96)
2770     FUNC(get_nd_value_ev96)
2771     FUNC(get_nd_current_ev96)
2772     FUNC(get_current_av96)
2773     FUNC(get_current_tv96)
2774     FUNC(get_imager_active)
2775 
2776     FUNC(set_av96_direct)
2777     FUNC(set_av96)
2778     FUNC(set_focus)
2779     FUNC(set_focus_interlock_bypass)
2780     FUNC(set_iso_mode)
2781     FUNC(set_iso_real)
2782     FUNC(set_led)
2783     FUNC(set_nd_filter)
2784     FUNC(set_prop)
2785     FUNC(set_prop_str)
2786     FUNC(set_raw_nr)
2787     FUNC(set_raw)
2788     FUNC(set_sv96)
2789     FUNC(set_tv96_direct)
2790     FUNC(set_tv96)
2791     FUNC(set_user_av_by_id_rel)
2792     FUNC(set_user_av_by_id)
2793     FUNC(set_user_av96)
2794     FUNC(set_user_tv_by_id_rel)
2795     FUNC(set_user_tv_by_id)
2796     FUNC(set_user_tv96)
2797     FUNC(set_zoom_speed)
2798     FUNC(set_zoom_rel)
2799     FUNC(set_zoom)
2800 
2801     FUNC(wait_click)
2802     FUNC(is_pressed)
2803     FUNC(is_key)
2804     FUNC(set_exit_key)
2805     FUNC(wheel_right)
2806     FUNC(wheel_left)
2807     FUNC(md_get_cell_diff)
2808     FUNC(md_get_cell_val)
2809     FUNC(md_detect_motion)
2810     FUNC(md_af_led_control)
2811     FUNC(autostarted)
2812     FUNC(get_autostart)
2813     FUNC(set_autostart)
2814     FUNC(get_usb_power)
2815     FUNC(set_remote_timing)
2816     FUNC(usb_force_active)
2817     FUNC(usb_sync_wait)
2818     FUNC(enter_alt)
2819     FUNC(exit_alt)
2820     FUNC(get_alt_mode)
2821     FUNC(shut_down)
2822     FUNC(print_screen)
2823 
2824     FUNC(get_partitionInfo)
2825     FUNC(swap_partitions)
2826 
2827     FUNC(get_focus_mode)
2828     FUNC(get_focus_state)
2829     FUNC(get_focus_ok)
2830     FUNC(get_propset)
2831     FUNC(get_zoom_steps)
2832     FUNC(get_drive_mode)
2833     FUNC(get_flash_mode)
2834     FUNC(get_shooting)
2835     FUNC(get_flash_ready)
2836     FUNC(get_IS_mode)
2837     FUNC(set_ev)
2838     FUNC(get_ev)
2839     FUNC(get_orientation_sensor)
2840     FUNC(get_nd_present)
2841     FUNC(get_movie_status)
2842     FUNC(set_movie_status)
2843     FUNC(get_video_button)
2844     FUNC(get_video_recording)
2845  
2846     FUNC(get_histo_range)
2847     FUNC(shot_histo_enable)
2848     FUNC(shot_histo_write_to_file)
2849     FUNC(get_live_histo)
2850     FUNC(play_sound)
2851     FUNC(get_temperature)
2852     FUNC(peek)
2853     FUNC(poke)
2854     FUNC(bitand)
2855     FUNC(bitor)
2856     FUNC(bitxor)
2857     FUNC(bitshl)
2858     FUNC(bitshri)
2859     FUNC(bitshru)
2860     FUNC(bitnot)
2861 
2862     FUNC(get_time)
2863 
2864     FUNC(get_buildinfo)
2865     FUNC(get_mode)
2866 
2867     FUNC(set_raw_develop)
2868     // NOTE these functions normally run in the spytask.
2869     // called from lua they will run from kbd task instead
2870     FUNC(raw_merge_start)
2871     FUNC(raw_merge_add_file)
2872     FUNC(raw_merge_end)
2873     FUNC(set_backlight)
2874     FUNC(set_lcd_display)
2875     FUNC(set_draw_title_line)
2876     FUNC(get_draw_title_line)
2877     FUNC(set_aelock)
2878     FUNC(set_aflock)
2879     FUNC(set_mf)
2880     FUNC(get_sd_over_modes)
2881     FUNC(set_curve_state)
2882     FUNC(get_curve_state)
2883     FUNC(set_curve_file)
2884     FUNC(get_curve_file)
2885     // get levent definition by name or id, nil if not found
2886     FUNC(get_levent_def)
2887     // get levent definition by index, nil if out of range
2888     FUNC(get_levent_def_by_index)
2889     // get levent index from name or ID
2890     FUNC(get_levent_index)
2891     FUNC(post_levent_to_ui)
2892     FUNC(post_levent_for_npt)
2893     FUNC(set_levent_active)
2894     FUNC(set_levent_script_mode)
2895 
2896     FUNC(set_capture_mode)
2897     FUNC(set_capture_mode_canon)
2898     FUNC(is_capture_mode_valid)
2899 
2900     FUNC(set_record)
2901 
2902     FUNC(switch_mode_usb)
2903 
2904     FUNC(call_event_proc)
2905     FUNC(call_func_ptr)
2906     FUNC(reboot)
2907     FUNC(get_config_value)
2908     FUNC(set_config_value)
2909     FUNC(set_config_autosave)
2910     FUNC(save_config_file)
2911     FUNC(load_config_file)
2912     FUNC(set_file_attributes)
2913     FUNC(get_meminfo)
2914     FUNC(file_browser)
2915     FUNC(textbox)
2916     FUNC(draw_pixel)
2917     FUNC(draw_line)
2918     FUNC(draw_rect)
2919     FUNC(draw_rect_filled)
2920     FUNC(draw_ellipse)
2921     FUNC(draw_ellipse_filled)
2922     FUNC(draw_clear)
2923     FUNC(draw_string)
2924 
2925     FUNC(get_gui_screen_width)
2926     FUNC(get_gui_screen_height)
2927 
2928     FUNC(set_yield)
2929     FUNC(read_usb_msg)
2930     FUNC(write_usb_msg)
2931     FUNC(get_usb_capture_support)
2932     FUNC(init_usb_capture)
2933     FUNC(get_usb_capture_target)
2934     FUNC(set_usb_capture_timeout)
2935 
2936     FUNC(iso_to_sv96)
2937     FUNC(sv96_to_iso)
2938     FUNC(iso_real_to_market)
2939     FUNC(iso_market_to_real)
2940     FUNC(sv96_real_to_market)
2941     FUNC(sv96_market_to_real)
2942     FUNC(aperture_to_av96)
2943     FUNC(av96_to_aperture)
2944     FUNC(usec_to_tv96)
2945     FUNC(tv96_to_usec)
2946     FUNC(seconds_to_tv96)
2947 
2948     {NULL, NULL},
2949 };
2950 
2951 void register_shoot_hook_fn(lua_State* L, int hook, void *hook_fn, const char *name)
2952 {
2953     lua_pushnumber( L, hook );
2954     lua_pushcclosure( L, hook_fn, 1 );
2955     lua_setfield( L, -2, name);
2956 }
2957 
2958 void register_shoot_hooks( lua_State* L )
2959 {
2960     int i;
2961     for(i=0; i<SCRIPT_NUM_SHOOT_HOOKS;i++) {
2962         lua_createtable(L, 0, 4);
2963         register_shoot_hook_fn(L,i,luaCB_shoot_hook_set,"set");
2964 //        register_shoot_hook_fn(L,i,luaCB_shoot_hook_wait_ready,"wait_ready");
2965         register_shoot_hook_fn(L,i,luaCB_shoot_hook_is_ready,"is_ready");
2966         register_shoot_hook_fn(L,i,luaCB_shoot_hook_continue,"continue");
2967         register_shoot_hook_fn(L,i,luaCB_shoot_hook_count,"count");
2968         lua_setglobal( L, shoot_hook_names[i] );
2969     }
2970 }
2971 
2972 void register_lua_funcs( lua_State* L )
2973 {
2974   const luaL_reg *r;
2975 
2976   register_shoot_hooks( L );
2977   luaopen_rawop( L );
2978 
2979   lua_pushlightuserdata( L, action_push_click );
2980   lua_pushcclosure( L, luaCB_keyfunc, 1 );
2981   lua_setglobal( L, "click" );
2982 
2983   lua_pushlightuserdata( L, action_push_press );
2984   lua_pushcclosure( L, luaCB_keyfunc, 1 );
2985   lua_setglobal( L, "press" );
2986 
2987   lua_pushlightuserdata( L, action_push_release );
2988   lua_pushcclosure( L, luaCB_keyfunc, 1 );
2989   lua_setglobal( L, "release" );
2990 
2991   for(r=chdk_funcs;r->name;r++) {
2992     lua_pushcfunction( L, r->func );
2993     lua_setglobal( L, r->name );
2994   }
2995    luaL_dostring(L,"function usb_msg_table_to_string(t)"
2996                     " local v2s=function(v)"
2997                         " local t=type(v)"
2998                         " if t=='string' then return v end"
2999                         " if t=='number' or t=='boolean' or t=='nil' then return tostring(v) end"
3000                         " return '' end"
3001                     " local r=''"
3002                     " for k,v in pairs(t) do"
3003                         " local s,vs=''"
3004                         " if type(v)=='table' then"
3005                             " for i=1,table.maxn(v) do"
3006                             " s=s..'\\t'..v2s(v[i]) end"
3007                         " else"
3008                             " vs=v2s(v)"
3009                             " if #vs then s=s..'\\t'..vs end"
3010                         " end"
3011                         " vs=v2s(k)"
3012                         " if #vs>0 and #s>0 then r=r..vs..s..'\\n' end"
3013                     " end"
3014                     " return r"
3015                    " end");
3016 
3017 }
3018 
3019 // =========  MODULE INIT =================
3020 
3021 /***************** BEGIN OF AUXILARY PART *********************
3022   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
3023  **************************************************************/
3024 
3025 static void lua_set_variable(char *name, int value, int isBool, int isTable, int labelCount, const char **labels)
3026 {
3027     lua_pushstring( L, name );
3028     if (isTable)
3029     {
3030         lua_createtable(L, labelCount, 2);
3031         int i;
3032         for (i=0; i<labelCount; i++)
3033         {
3034             lua_pushstring(L,labels[i]);
3035             lua_rawseti(L,-2,i+1);
3036         }
3037         SET_INT_FIELD("index", value+1);        // Make value 1 based for Lua table index
3038         SET_STR_FIELD("value", labels[value]);
3039     }
3040     else
3041     {
3042         if (isBool)
3043             lua_pushboolean( L, value );
3044         else
3045             lua_pushnumber( L, value );
3046     }
3047     lua_settable( L, LUA_GLOBALSINDEX );
3048 }
3049 
3050 static void lua_set_as_ret(int md_ret)                  { lua_pushnumber(Lt,md_ret); }
3051 
3052 /******************** Module Information structure ******************/
3053 
3054 libscriptapi_sym _liblua =
3055 {
3056     {
3057          0, 0, 0, 0, 0
3058     },
3059 
3060     lua_script_start,
3061     lua_script_start_file,
3062     lua_script_run,
3063     lua_script_reset,
3064     lua_set_variable,
3065     lua_set_as_ret,
3066     lua_run_restore,
3067     script_shoot_hook_run,
3068 };
3069 
3070 ModuleInfo _module_info =
3071 {
3072     MODULEINFO_V1_MAGICNUM,
3073     sizeof(ModuleInfo),
3074     SCRIPT_API_VERSION,         // Module version
3075 
3076     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,   // Requirements of CHDK version
3077     ANY_PLATFORM_ALLOWED,       // Specify platform dependency
3078 
3079     -LANG_MODULE_LUA,           // Module name
3080     MTYPE_SCRIPT_LANG,          //Run Lua Scripts
3081 
3082     &_liblua.base,
3083 
3084     CONF_VERSION,               // CONF version
3085     CAM_SCREEN_VERSION,         // CAM SCREEN version
3086     CAM_SENSOR_VERSION,         // CAM SENSOR version
3087     CAM_INFO_VERSION,           // CAM INFO version
3088 };
3089 
3090 /*************** END OF AUXILARY PART *******************/

/* [<][>][^][v][top][bottom][index][help] */