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 = ttm->tm_sec;
1639   else if (strncmp("m", t, 1)==0) r = ttm->tm_min;
1640   else if (strncmp("h", t, 1)==0) r = ttm->tm_hour;
1641   else if (strncmp("D", t, 1)==0) r = ttm->tm_mday;
1642   else if (strncmp("M", t, 1)==0) r = ttm->tm_mon+1;
1643   else if (strncmp("Y", t, 1)==0) r = 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, 10);
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   set_number_field( L,"digic", camera_info.cam_digic );
1802   return 1;
1803 }
1804 
1805 static int luaCB_get_mode( lua_State* L )
1806 {
1807   lua_pushboolean( L, !camera_info.state.mode_play );
1808   lua_pushboolean( L, camera_info.state.mode_video );
1809   lua_pushnumber( L, camera_info.state.mode );
1810   return 3;
1811 }
1812 
1813 // TODO sanity check file ?
1814 static int luaCB_set_raw_develop( lua_State* L )
1815 {
1816   raw_prepare_develop(luaL_optstring( L, 1, NULL ), 0);
1817   return 0;
1818 }
1819 
1820 static int luaCB_raw_merge_start( lua_State* L )
1821 {
1822     int op = luaL_checknumber(L,1);
1823     if ((op == RAW_OPERATION_SUM || op == RAW_OPERATION_AVERAGE))
1824     {
1825         lua_pushboolean(L, librawop->raw_merge_start(op));   
1826         return 1;
1827     }
1828     else {
1829         return luaL_argerror(L,1,"invalid raw merge op");
1830     }
1831 }
1832 
1833 // TODO sanity check file ? Get it from C
1834 static int luaCB_raw_merge_add_file( lua_State* L )
1835 {
1836     lua_pushboolean(L, librawop->raw_merge_add_file(luaL_checkstring( L, 1 )));
1837     return 1;
1838 }
1839 
1840 static int luaCB_raw_merge_end( lua_State* L )
1841 {
1842     librawop->raw_merge_end();
1843     return 0;
1844 }
1845 
1846 // Enable/disable LCD back light (input argument 1/0)
1847 static int luaCB_set_backlight( lua_State* L )
1848 {
1849   int val = on_off_value_from_lua_arg(L,1);
1850 
1851   if (val > 0) TurnOnBackLight();
1852   else TurnOffBackLight();
1853   return 0;
1854 }
1855 
1856 // Enable/disable LCD display (input argument 1/0)
1857 static int luaCB_set_lcd_display( lua_State* L )
1858 {
1859   int val = on_off_value_from_lua_arg(L,1);
1860 
1861   if (val > 0) TurnOnDisplay();
1862   else TurnOffDisplay();
1863   return 0;
1864 }
1865 
1866 // Enable/disable CHDK <ALT> & scriptname OSD items (input argument 1/0)
1867 static int luaCB_set_draw_title_line( lua_State* L )
1868 {
1869   camera_info.state.osd_title_line= on_off_value_from_lua_arg(L,1);
1870   return 0;
1871 }
1872 
1873 // get CHDK <ALT> & scriptname OSD display state (input argument 1/0)
1874 static int luaCB_get_draw_title_line( lua_State* L )
1875 {
1876    lua_pushboolean( L, camera_info.state.osd_title_line  );
1877    return 1;
1878 }
1879 
1880 // get the string or number passed in index and return it as an event id
1881 static unsigned levent_id_from_lua_arg( lua_State* L, int index)
1882 {
1883   unsigned event_id;
1884   if (lua_type(L, index) == LUA_TSTRING) {
1885     const char *ev_name = lua_tostring(L, index);
1886     event_id = levent_id_for_name(ev_name);
1887     if (event_id == 0) {
1888         return luaL_error( L, "bad event name '%s'", ev_name );
1889     }
1890   }
1891   // could check here if it is in the table, but even valid ones can crash
1892   // so we avoid searching the table if given a number
1893   else if (lua_type(L,index) == LUA_TNUMBER){
1894     event_id = lua_tonumber(L,index);
1895   }
1896   else {
1897     return luaL_error( L, "expected event name or id" );
1898   }
1899   return event_id;
1900 }
1901 
1902 
1903 /*
1904   return the index of an event, given it's name or event id
1905 */
1906 static unsigned levent_index_from_id_lua_arg( lua_State* L, int index )
1907 {
1908   if (lua_type(L, index) == LUA_TSTRING) {
1909     return levent_index_for_name(lua_tostring(L, index));
1910   }
1911   else if (lua_type(L,index) == LUA_TNUMBER){
1912     return levent_index_for_id(lua_tonumber(L,index));
1913   }
1914   else {
1915     return luaL_error( L, "expected string or number" );
1916   }
1917 }
1918 
1919 /*
1920   name,id,param = get_levent_def(event)
1921   event is an event id (number) or name (string)
1922   returns nil if event is not found
1923 */
1924 static int luaCB_get_levent_def( lua_State* L )
1925 {
1926   unsigned event_index = levent_index_from_id_lua_arg(L,1);
1927   if (event_index == LEVENT_INVALID_INDEX) {
1928     lua_pushnil(L);
1929     return 1;
1930   }
1931   lua_pushstring(L, levent_table[event_index].name);
1932   lua_pushnumber(L, levent_table[event_index].id);
1933   lua_pushnumber(L, levent_table[event_index].param);
1934   return 3;
1935 }
1936 
1937 /*
1938   index=get_levent_index(event)
1939   event is an event id (number) or name (string)
1940   returns index or nil if not found
1941 */
1942 static int luaCB_get_levent_index( lua_State* L )
1943 {
1944   unsigned event_index = levent_index_from_id_lua_arg(L,1);
1945   if (event_index == LEVENT_INVALID_INDEX) {
1946     lua_pushnil(L);
1947   }
1948   else {
1949     lua_pushnumber(L, event_index);
1950   }
1951   return 1;
1952 }
1953 
1954 /*
1955   name,id,param = get_levent_def_by_index(event_index)
1956   event_index is number index into the event table
1957   returns nil if event is not found
1958 */
1959 static int luaCB_get_levent_def_by_index( lua_State* L )
1960 {
1961   unsigned i = luaL_checknumber(L,1);
1962   if(i >= levent_count()) {
1963     lua_pushnil(L);
1964     return 1;
1965   }
1966   lua_pushstring(L, levent_table[i].name);
1967   lua_pushnumber(L, levent_table[i].id);
1968   lua_pushnumber(L, levent_table[i].param);
1969   return 3;
1970 }
1971 
1972 /*
1973   post_levent_*(event[,unk])
1974   post the event with PostLogicalEventToUI or PostLogicaEventForNotPowerType
1975   This sends the event. The difference between functions isn't clear.
1976   event is an event id (number) or name (string).
1977   unk is an optional number whose meaning is unknown, defaults to zero. 
1978     Based on code, other values would probably be a pointer.
1979     This is NOT the 3rd item in the event table.
1980 */
1981 static int luaCB_post_levent_to_ui( lua_State* L )
1982 {
1983   unsigned event_id,arg;
1984 
1985   event_id = levent_id_from_lua_arg(L,1);
1986   arg = luaL_optnumber(L, 2, 0);
1987   PostLogicalEventToUI(event_id,arg);
1988   return 0;
1989 }
1990 
1991 static int luaCB_post_levent_for_npt( lua_State* L )
1992 {
1993   unsigned event_id,arg;
1994 
1995   event_id = levent_id_from_lua_arg(L,1);
1996   arg = luaL_optnumber(L, 2, 0);
1997   PostLogicalEventForNotPowerType(event_id,arg);
1998   return 0;
1999 }
2000 
2001 /*
2002   set_levent_active(event,state)
2003   event is an event id (number) or name (string)
2004   state is a numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
2005   exact meaning is unknown, but it has something to do with the delivery of the specified event.
2006 */
2007 static int luaCB_set_levent_active( lua_State* L )
2008 {
2009   unsigned event_id;
2010   unsigned state;
2011 
2012   event_id = levent_id_from_lua_arg(L,1);
2013   state = on_off_value_from_lua_arg(L,2);
2014   SetLogicalEventActive(event_id,state);
2015   return 0;
2016 }
2017 
2018 /*
2019   set_levent_script_mode(state)
2020   state is numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
2021   exact meaning is unknown, but it has something to do with the behavior of events and/or SetLogicalEventActive.
2022 */
2023 static int luaCB_set_levent_script_mode( lua_State* L )
2024 {
2025   SetScriptMode(on_off_value_from_lua_arg(L,1));
2026   return 0;
2027 }
2028 
2029 /* 
2030   result=set_capture_mode_canon(value)
2031   where value is a valid PROPCASE_SHOOTING_MODE value for the current camera
2032   result is true if the camera is in rec mode
2033 */
2034 static int luaCB_set_capture_mode_canon( lua_State* L )
2035 {
2036   int modenum = luaL_checknumber(L,1);
2037   // if the value as negative, assume it is a mistakenly sign extended PROPCASE_SHOOTING_MODE value
2038   if(modenum < 0) 
2039     modenum &= 0xFFFF;
2040   lua_pushboolean( L, shooting_set_mode_canon(modenum) );
2041   return 1;
2042 }
2043 
2044 /*
2045  result=set_capture_mode(modenum)
2046  where modenum is a valid CHDK modemap value
2047  result is true if modenum is a valid modemap value, otherwise false
2048 */
2049 static int luaCB_set_capture_mode( lua_State* L )
2050 {
2051   int modenum = luaL_checknumber(L,1);
2052   lua_pushboolean( L, shooting_set_mode_chdk(modenum) );
2053   return 1;
2054 }
2055 
2056 /*
2057  result=is_capture_mode_valid(modenum)
2058  where modenum is a valid CHDK modemap value
2059  result is true if modenum is a valid modemap value, otherwise false
2060 */
2061 static int luaCB_is_capture_mode_valid( lua_State* L )
2062 {
2063   int modenum = luaL_checknumber(L,1);
2064   lua_pushboolean( L, shooting_mode_chdk2canon(modenum) != -1 );
2065   return 1;
2066 }
2067 
2068 /* 
2069   set_record(state)
2070   if state is 0 (or false) the camera is set to play mode. If 1 or true, the camera is set to record mode.
2071   NOTE: this only begins the mode change. Script should wait until get_mode() reflects the change,
2072   before doing anything that requires the new mode. e.g.
2073   set_record(true)
2074   while not get_mode() do
2075     sleep(10)
2076   end
2077   uses switch_mode_usb if required
2078 */
2079 static int luaCB_set_record( lua_State* L )
2080 {
2081   shooting_set_playrec_mode(on_off_value_from_lua_arg(L,1));
2082   return 0;
2083 }
2084 
2085 // switch mode (0 = playback, 1 = record)
2086 // only for when USB is connected
2087 static int luaCB_switch_mode_usb( lua_State* L )
2088 {
2089   switch_mode_usb(on_off_value_from_lua_arg(L,1));
2090   return 0;
2091 }
2092  
2093 /*
2094 pack the lua args into a buffer to pass to the native code calling functions 
2095 currently only handles strings/numbers
2096 start is the stack index of the first arg
2097 */
2098 static int pack_native_args( lua_State* L, unsigned start, unsigned *argbuf)
2099 {
2100   unsigned i;
2101   unsigned end = lua_gettop(L);
2102 
2103   for(i = start; i <= end; i++,argbuf++) {
2104     if (lua_type(L, i) == LUA_TSTRING) {
2105         *argbuf=(unsigned)lua_tostring( L, i);
2106     }
2107     else if (lua_type(L, i) == LUA_TNUMBER) {
2108         *argbuf=lua_tonumber( L, i);
2109     }
2110     else {
2111       return 0;
2112     }
2113   }
2114   return 1;
2115 }
2116 
2117 /*
2118 Native function call interface. Can be used to call canon eventprocs or arbitrary
2119 pointers.
2120 
2121 NOTE: this is preliminary, interface may change in later versions!
2122 All arguments must be strings or numbers.
2123 If the function expects to modify it's arguments via a pointer,
2124 then you must provide a number that is a valid pointer. 
2125 
2126 You can use the "AllocateMemory" eventproc to obtain buffers.
2127 
2128 If the function tries to write to a string passed from lua, Bad Things may happen.
2129 
2130 This is potentially dangerous, functions exist which can destroy the onboard firmware.
2131 */
2132 
2133 /*
2134 result=call_func_ptr(ptr,...)
2135 ptr: address of a valid ARM or Thumb function, which uses the normal C calling convention.
2136 result: R0 value after the call returns
2137 */
2138 static int luaCB_call_func_ptr( lua_State* L)
2139 {
2140     if (conf.script_allow_lua_native_calls)
2141     {
2142         unsigned *argbuf=NULL;
2143         unsigned n_args = lua_gettop(L)-1;
2144         void *fptr;
2145 
2146         fptr=(void *)luaL_checknumber( L, 1 );
2147 
2148         if (n_args)
2149         {
2150             argbuf=malloc(n_args * 4);
2151             if(!argbuf)
2152             {
2153                 return luaL_error( L, "malloc fail" );
2154             }
2155             if(!pack_native_args(L, 2, argbuf))
2156             {
2157                 free(argbuf);
2158                 return luaL_error( L, "expected string or number" );
2159             }
2160         }
2161           
2162         lua_pushnumber( L, call_func_ptr(fptr, argbuf, n_args) );
2163         free(argbuf);
2164         return 1;
2165     }
2166     return luaL_error( L, "native calls disabled" );
2167 }
2168 
2169 /* 
2170 Call an event procedure
2171 
2172 result=call_event_proc("EventprocName",...)
2173 result is the value returned by ExecuteEventProcedure, which is -1 if the eventproc is not found, 
2174 or the eventproc return value (which could also be -1)
2175 NOTE:
2176 Many eventprocs are not registered by default, but can be loaded by calling another event proc
2177 Some useful ones are
2178 SystemEventInit
2179     includes AllocateMemory, FreeMemory, sprintf, memcpy, Fut functions, log ...
2180 UI_RegistDebugEventProc
2181     includes capture mode functions, PTM_ functions and much more 
2182 RegisterProductTestEvent
2183     includes PT_ functions
2184 
2185 Others:
2186 RegisterShootSeqEvent
2187 RegisterNRTableEvent
2188 */
2189 
2190 // grab from lowlevel
2191 extern unsigned _ExecuteEventProcedure(const char *name,...);
2192 static int luaCB_call_event_proc( lua_State* L )
2193 {
2194     if (conf.script_allow_lua_native_calls)
2195     {
2196         const char *evpname;
2197         unsigned *argbuf;
2198         unsigned n_args = lua_gettop(L);
2199 
2200         evpname=luaL_checkstring( L, 1 );
2201 
2202         argbuf=malloc(n_args * 4);
2203         if (!argbuf)
2204         {
2205             return luaL_error( L, "malloc fail" );
2206         }
2207 
2208         // event proc name is first arg
2209         *argbuf = (unsigned)evpname;
2210   
2211         if(!pack_native_args(L,2,argbuf+1))
2212         {
2213             free(argbuf);
2214             return luaL_error( L, "expected string or number" );
2215         }
2216   
2217         lua_pushnumber( L, call_func_ptr(_ExecuteEventProcedure,argbuf,n_args) );
2218         free(argbuf);
2219         return 1;
2220     }
2221     return luaL_error( L, "native calls disabled" );
2222 }
2223 
2224 /*
2225 result = reboot(["filename"])
2226 returns false on failure, does not return on success
2227 see lib/armutil/reboot.c for details
2228 */
2229 static int luaCB_reboot( lua_State* L )
2230 {
2231     lua_pushboolean(L, reboot(luaL_optstring( L, 1, NULL )));
2232     return 1;
2233 }
2234 
2235 static int luaCB_get_config_value( lua_State* L ) {
2236     unsigned int argc = lua_gettop(L);
2237     unsigned int id, i;
2238     int ret = 1;
2239     tConfigVal configVal;
2240     
2241     if( argc>=1 ) {
2242         id = luaL_checknumber(L, 1);
2243         switch( conf_getValue(id, &configVal) ) {
2244             case CONF_VALUE:
2245                 lua_pushnumber(L, configVal.numb);
2246             break;
2247             case CONF_INT_PTR:
2248                 lua_createtable(L, 0, configVal.numb);
2249                 for( i=0; i<configVal.numb; i++ ) {
2250                     lua_pushinteger(L, configVal.pInt[i]);
2251                     lua_rawseti(L, -2, i+1);  //t[i+1]=configVal.pInt[i]
2252                 }
2253             break;
2254             case CONF_CHAR_PTR:
2255                 lua_pushstring(L, configVal.str);
2256             break;
2257             case CONF_OSD_POS:
2258                 lua_pushnumber(L, configVal.pos.x);
2259                 lua_pushnumber(L, configVal.pos.y); ret++;
2260             break;
2261             default:
2262                 if( argc>=2) { //Default
2263                     ret = argc-1;
2264                 } else {
2265                     lua_pushnil(L);
2266                 }
2267             break;
2268         }
2269     } else {
2270         lua_pushnil(L);
2271     }
2272     return ret;
2273 }
2274 
2275 static int luaCB_set_config_value( lua_State* L ) {
2276     unsigned int argc = lua_gettop(L);
2277     unsigned int id, i, j;
2278     tConfigVal configVal = {0,0,0,0};  //initialize isXXX
2279     
2280     if( argc>=2 ) {
2281         id = luaL_checknumber(L, 1);
2282         for( i=2; i<=argc; i++) {
2283             switch( lua_type(L, i) ) {
2284                 case LUA_TNUMBER:
2285                     if( !configVal.isNumb ) {
2286                         configVal.numb = luaL_checknumber(L, i);
2287                         configVal.isNumb++;
2288                     }
2289                     switch( configVal.isPos ) {
2290                         case 0: configVal.pos.x = luaL_checknumber(L, i); configVal.isPos++; break;
2291                         case 1: configVal.pos.y = luaL_checknumber(L, i); configVal.isPos++; break;
2292                     }
2293                 break;
2294                 case LUA_TSTRING:
2295                     if( !configVal.isStr ) {
2296                         configVal.str = (char*)luaL_checkstring(L, i);
2297                         configVal.isStr++;
2298                     }
2299                 break;
2300                 case LUA_TTABLE:
2301                     if( !configVal.isPInt ) {
2302                         configVal.numb = lua_objlen(L, i);
2303                         if( configVal.pInt ) {
2304                             free(configVal.pInt);
2305                             configVal.pInt = NULL;
2306                         }
2307                         configVal.pInt = malloc(configVal.numb*sizeof(int));
2308                         if( configVal.pInt ) {
2309                             for( j=1; j<=configVal.numb; j++) {
2310                                 lua_rawgeti(L, i, j);
2311                                 configVal.pInt[j-1] = lua_tointeger(L, -1);
2312                                 lua_pop(L, 1);
2313                             }
2314                         }
2315                         configVal.isPInt++;
2316                     }
2317                 break;
2318             }
2319         }
2320         lua_pushboolean(L, conf_setValue(id, configVal));
2321         if( configVal.pInt ) {
2322             free(configVal.pInt);
2323             configVal.pInt = NULL;
2324         }
2325     } else lua_pushboolean(L, 0);
2326     return 1;
2327 }
2328 
2329 static int luaCB_set_config_autosave( lua_State* L ) {
2330     conf_setAutosave(on_off_value_from_lua_arg(L, 1));
2331     return 0;
2332 }
2333 
2334 static int luaCB_save_config_file( lua_State* L ) {
2335     lua_pushboolean(L, save_config_file(luaL_checknumber(L, 1), luaL_optstring(L, 2, NULL)));
2336     return 1;
2337 }
2338 
2339 static int luaCB_load_config_file( lua_State* L ) {
2340     lua_pushboolean(L, load_config_file(luaL_checknumber(L, 1), luaL_optstring(L, 2, NULL)));
2341     return 1;
2342 }
2343 
2344 static int luaCB_set_file_attributes( lua_State* L ) {
2345     lua_pushnumber(L, SetFileAttributes(luaL_checkstring(L, 1), luaL_checknumber(L, 2)));
2346     return 1;
2347 }
2348 
2349 static int action_stack_AS_SCRIPT_READ_USB_MSG()
2350 {
2351     ptp_script_msg *msg = ptp_script_read_msg();
2352 
2353     if ((get_tick_count() >= action_top(2)) || msg)
2354     {
2355         if (msg && msg->data)
2356         {
2357             lua_pushlstring(Lt,msg->data,msg->size);
2358         }
2359         else
2360         {
2361             lua_pushnil(Lt);
2362         }
2363         action_pop_func(1);
2364         return 1;
2365     }
2366     return 0;
2367 }
2368 
2369 static int action_stack_AS_SCRIPT_WRITE_USB_MSG()
2370 {
2371     ptp_script_msg *msg = (ptp_script_msg *)action_top(2);
2372 
2373     int r = ptp_script_write_msg(msg);
2374 
2375     if ((get_tick_count() >= action_top(3)) || r)
2376     {
2377         lua_pushboolean(Lt,r);
2378         action_pop_func(2);
2379         return 1;
2380     }
2381     return 0;
2382 }
2383 
2384 /*
2385 msg = read_usb_msg([timeout])
2386 read a message from the CHDK ptp interface.
2387 Returns the next available message as a string, or nil if no messages are available
2388 If timeout is given and not zero, wait until a message is available or timeout expires
2389 */
2390 static int luaCB_read_usb_msg( lua_State* L )
2391 {
2392   int timeout = sleep_delay(luaL_optnumber(L,1,0));
2393   if (timeout > 0)
2394   {
2395     action_push(timeout);
2396     action_push_func(action_stack_AS_SCRIPT_READ_USB_MSG);
2397     return lua_yield( L, 0 );
2398   }
2399   ptp_script_msg *msg = ptp_script_read_msg();
2400   if(msg)
2401   {
2402     lua_pushlstring(L,msg->data,msg->size);
2403     free(msg);
2404     return 1;
2405   }
2406   lua_pushnil(L);
2407   return 1;
2408 }
2409 
2410 /*
2411 status = write_usb_msg(msg,[timeout])
2412 writes a message to the CHDK ptp interface
2413 msg may be nil, boolean, number, string or table (table has some restrictions, will be converted to string)
2414 returns true if the message was queued successfully, otherwise false
2415 if timeout is set and not zero, wait until message is written or timeout expires
2416 NOTE strings will not include a terminating NULL, must be handled by recipient
2417 */
2418 static int luaCB_write_usb_msg( lua_State* L )
2419 {
2420   ptp_script_msg *msg;
2421   int timeout = sleep_delay(luaL_optnumber(L,2,0));
2422   // TODO would it be better to either ignore this or return nil ?
2423   // a write_usb_msg(function_which_returns_no_value()) is an error in this case
2424   // replacing with nil might be more luaish
2425   if (lua_gettop(L) < 1)
2426   {
2427     return luaL_error(L,"missing argument");
2428   }
2429   msg=lua_create_usb_msg(L,1,PTP_CHDK_S_MSGTYPE_USER);
2430   // for user messages, trying to create a message from an incompatible type throws an error
2431   if (msg->subtype == PTP_CHDK_TYPE_UNSUPPORTED)
2432   {
2433     free(msg);
2434     return luaL_error(L,"unsupported type");
2435   }
2436   if (!msg)
2437   {
2438     return luaL_error(L,"failed to create message");
2439   }
2440   if (timeout)
2441   {
2442     action_push(timeout);
2443     action_push((int)msg);
2444     action_push_func(action_stack_AS_SCRIPT_WRITE_USB_MSG);
2445     return lua_yield( L, 0 );
2446   }
2447   lua_pushboolean(L,ptp_script_write_msg(msg)); 
2448   return 1;
2449 }
2450 
2451 /* helper for meminfo to set table field only if valid */
2452 static void set_meminfo_num( lua_State* L,const char *name, int val) {
2453     if(val != -1) {
2454         set_number_field( L, name, val );
2455     }
2456 }
2457 /*
2458 meminfo=get_meminfo([heapname])
2459 get camera memory information
2460 heapname="combined", "system", "aram" or "exmem" 
2461 if not given, combined is returned
2462 meminfo is false if the requested heapname isn't valid ("exmem" when exmem is not enabled, or unknown)
2463 otherwise, a table of the form
2464 meminfo = {
2465     name -- heapname, as above
2466     chdk_malloc -- bool, this is the heap used by CHDK for malloc
2467     chdk_start -- number, load address of CHDK
2468     chdk_size -- number, size of CHDK image
2469     -- all the following are numbers, will not be set if not available
2470     start_address
2471     end_address
2472     total_size
2473     allocated_size
2474     allocated_peak
2475     allocated_count
2476     free_size
2477     free_block_max_size
2478     free_block_count
2479 }
2480 NOTES
2481 * under vxworks and cameras without GetMemInfo only the only valid fields
2482   for the system heap will be those defined by chdk and free_block_max_size
2483 * the meaning of fields may not correspond exactly between exmem and system
2484 */
2485 static int luaCB_get_meminfo( lua_State* L ) {
2486     const char *heapname = luaL_optstring( L, 1, "combined" );
2487     cam_meminfo meminfo;
2488     if (strcmp(heapname,"combined") == 0) {
2489         GetCombinedMemInfo(&meminfo);
2490         meminfo.start_address=meminfo.end_address=-1; // not meaningful
2491     }
2492     else if (strcmp(heapname,"system") == 0)
2493     {
2494         GetMemInfo(&meminfo);
2495     }
2496     else if ((strcmp(heapname,"aram") == 0))
2497     {
2498         if(!GetARamInfo(&meminfo)) {
2499             lua_pushboolean(L,0);
2500             return 1;
2501         }
2502     }
2503     else if (strcmp(heapname,"exmem") == 0)
2504     {
2505         if(!GetExMemInfo(&meminfo)) {;
2506             lua_pushboolean(L,0);
2507             return 1;
2508         }
2509     }
2510     else
2511     {
2512         lua_pushboolean(L,0);
2513         return 1;
2514     }
2515     // adjust start and size, if CHDK is loaded at heap start
2516     if(meminfo.start_address == camera_info.text_start) {
2517         meminfo.start_address += camera_info.memisosize;
2518         meminfo.total_size -= camera_info.memisosize;
2519     }
2520     lua_createtable(L, 0, 13); // might not always use 13, but doesn't hurt
2521     set_string_field( L,"name", heapname );
2522     // CHDK allocates from all available heaps now
2523     lua_pushboolean( L, 1);
2524     lua_setfield(L, -2, "chdk_malloc");
2525     set_number_field( L, "chdk_start", camera_info.text_start);
2526     set_number_field( L, "chdk_size", camera_info.memisosize );
2527     set_meminfo_num( L, "start_address", meminfo.start_address );
2528     set_meminfo_num( L, "end_address", meminfo.end_address);
2529     set_meminfo_num( L, "total_size", meminfo.total_size);
2530     set_meminfo_num( L, "allocated_size", meminfo.allocated_size);
2531     set_meminfo_num( L, "allocated_peak", meminfo.allocated_peak);
2532     set_meminfo_num( L, "allocated_count", meminfo.allocated_count);
2533     set_meminfo_num( L, "free_size", meminfo.free_size);
2534     set_meminfo_num( L, "free_block_max_size", meminfo.free_block_max_size);
2535     set_meminfo_num( L, "free_block_count", meminfo.free_block_count);
2536     return 1;
2537 }
2538 
2539 /*
2540 set scheduling parameters
2541 old_max_count,old_max_ms=set_yield(max_count,max_ms)
2542 */
2543 static int luaCB_set_yield( lua_State* L )
2544 {
2545   lua_pushnumber(L,yield_max_count);
2546   lua_pushnumber(L,yield_max_ms);
2547   yield_max_count = luaL_optnumber(L,1,YIELD_MAX_COUNT_DEFAULT);
2548   yield_max_ms = luaL_optnumber(L,2,YIELD_MAX_MS_DEFAULT);
2549   return 2;
2550 }
2551 
2552 //static void register_func( lua_State* L, const char *name, void *func) {
2553 //  lua_pushcfunction( L, func );
2554 //  lua_setglobal( L, name );
2555 //}
2556 /*
2557 get remote capture supported types
2558 bitmask=get_usb_capture_support()
2559 */
2560 static int luaCB_get_usb_capture_support( lua_State* L )
2561 {
2562     lua_pushnumber(L,remotecap_get_target_support());
2563     return 1;
2564 }
2565 
2566 /*
2567 status=init_usb_capture(bitmask[,startline, numlines])
2568 bitmask = 0 clear usb capture mode
2569 
2570 lines only applies to raw
2571 startline defaults to 0
2572 numlines defaults to full buffer
2573 */
2574 static int luaCB_init_usb_capture( lua_State* L )
2575 {
2576     int what=luaL_checknumber(L, 1);
2577     int startline=luaL_optnumber(L, 2, 0);
2578     int numlines=luaL_optnumber(L, 3, 0);
2579     lua_pushboolean(L,remotecap_set_target(what,startline,numlines));
2580     return 1;
2581 }
2582 
2583 /*
2584 selected=get_usb_capture_target()
2585 selected = bitmask passed to init, or 0 if capture not configured or timed out/canceled
2586 */
2587 static int luaCB_get_usb_capture_target( lua_State* L )
2588 {
2589     lua_pushnumber(L,remotecap_get_target());
2590     return 1;
2591 }
2592 
2593 /*
2594 set_remotecap_timeout([timeout])
2595 timeout:
2596 number of milliseconds remote capture waits for data of each type to be downloaded
2597 <=0 or no value resets to the default value
2598 If any data type is not downloaded before the timeout expires, remote capture is canceled
2599 and none of the subsequent data types will be returned
2600 following a timeout, RemoteCaptureIsReady and RemoteCaptureGetData will behave as if
2601 remote capture were not initialized
2602 If the timeout expires while a transfer is in progress, an error will be generated
2603 and the data may be incomplete or corrupt
2604 */
2605 static int luaCB_set_usb_capture_timeout( lua_State* L )
2606 {
2607     remotecap_set_timeout(luaL_optnumber(L,1,0));
2608     return 0;
2609 }
2610 
2611 //------------------------------------------------------------------------------------------
2612 // APEX conversion functions
2613 
2614 static int luaCB_iso_to_sv96( lua_State* L )
2615 {
2616   lua_pushnumber(L, shooting_get_sv96_from_iso(luaL_checknumber(L, 1)));
2617   return 1;
2618 }
2619 
2620 static int luaCB_sv96_to_iso( lua_State* L )
2621 {
2622   lua_pushnumber(L, shooting_get_iso_from_sv96(luaL_checknumber(L, 1)));
2623   return 1;
2624 }
2625 
2626 static int luaCB_iso_real_to_market( lua_State* L )
2627 {
2628   lua_pushnumber(L, shooting_iso_real_to_market(luaL_checknumber(L, 1)));
2629   return 1;
2630 }
2631 
2632 static int luaCB_iso_market_to_real( lua_State* L )
2633 {
2634   lua_pushnumber(L, shooting_iso_market_to_real(luaL_checknumber(L, 1)));
2635   return 1;
2636 }
2637 
2638 static int luaCB_sv96_real_to_market( lua_State* L )
2639 {
2640   lua_pushnumber(L, shooting_sv96_real_to_market(luaL_checknumber(L, 1)));
2641   return 1;
2642 }
2643 
2644 static int luaCB_sv96_market_to_real( lua_State* L )
2645 {
2646   lua_pushnumber(L, shooting_sv96_market_to_real(luaL_checknumber(L, 1)));
2647   return 1;
2648 }
2649 
2650 static int luaCB_aperture_to_av96( lua_State* L )
2651 {
2652   lua_pushnumber(L, shooting_get_av96_from_aperture(luaL_checknumber(L, 1)));
2653   return 1;
2654 }
2655 
2656 static int luaCB_av96_to_aperture( lua_State* L )
2657 {
2658   lua_pushnumber(L, shooting_get_aperture_from_av96(luaL_checknumber(L, 1)));
2659   return 1;
2660 }
2661 
2662 static int luaCB_usec_to_tv96( lua_State* L )
2663 {
2664   lua_pushnumber(L, shooting_get_tv96_from_shutter_speed((float)luaL_checknumber(L, 1)/1000000.0));
2665   return 1;
2666 }
2667 
2668 static int luaCB_tv96_to_usec( lua_State* L )
2669 {
2670   lua_pushnumber(L, (int)(shooting_get_shutter_speed_from_tv96(luaL_checknumber(L, 1)) * 1000000.0 + 0.5));
2671   return 1;
2672 }
2673 
2674 static int luaCB_seconds_to_tv96( lua_State* L )
2675 {
2676   lua_pushnumber(L, shooting_get_tv96_from_shutter_speed((float)luaL_checknumber(L, 1)/(float)luaL_checknumber(L, 2)));
2677   return 1;
2678 }
2679 
2680 //------------------------------------------------------------------------------------------
2681 // Shoot hooks
2682 
2683 /*
2684 hook.set(timeout)
2685 cause hook to block shooting process until timeout or script issues hook.continue
2686 0 clears
2687 */
2688 static int luaCB_shoot_hook_set( lua_State* L )
2689 {
2690     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2691     script_shoot_hook_set(hook,luaL_checknumber(L, 1));
2692     return 0;
2693 }
2694 
2695 /*
2696 hook.is_ready()
2697 returns true if the hooked task is in the hook
2698 */
2699 static int luaCB_shoot_hook_is_ready( lua_State* L )
2700 {
2701     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2702     lua_pushboolean(L,script_shoot_hook_ready(hook));
2703     return 1;
2704 }
2705 
2706 /*
2707 hook.continue()
2708 allow the hooked task to leave the hook
2709 */
2710 static int luaCB_shoot_hook_continue( lua_State* L )
2711 {
2712     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2713     script_shoot_hook_continue(hook);
2714     return 0;
2715 }
2716 
2717 /*
2718 n=hook.count()
2719 return the number of times the hook has been reached since script start
2720 note: counts regardless of whether hook is enabled
2721 */
2722 static int luaCB_shoot_hook_count( lua_State* L )
2723 {
2724     int hook = lua_tonumber( L, lua_upvalueindex(1) );
2725     lua_pushnumber(L,script_shoot_hook_count(hook));
2726     return 1;
2727 }
2728 
2729 //------------------------------------------------------------------------------------------
2730 
2731 #define FUNC( X ) { #X, luaCB_##X },
2732 static const luaL_Reg chdk_funcs[] = {
2733     FUNC(shoot)
2734     FUNC(sleep)
2735     FUNC(cls)
2736     FUNC(set_console_layout)
2737     FUNC(set_console_autoredraw)
2738     FUNC(console_redraw)
2739     FUNC(get_av96)
2740     FUNC(get_bv96)
2741     FUNC(get_day_seconds)
2742     FUNC(get_disk_size)
2743     FUNC(get_dofinfo)
2744     FUNC(get_free_disk_space)
2745     FUNC(get_focus)
2746     FUNC(get_iso_market)
2747     FUNC(get_iso_mode)
2748     FUNC(get_iso_real)
2749     FUNC(get_jpg_count)
2750     FUNC(get_prop)
2751     FUNC(get_prop_str)
2752     FUNC(get_raw_support)
2753     FUNC(get_raw_count)
2754     FUNC(get_raw_nr)
2755     FUNC(get_raw)
2756     FUNC(get_sv96)
2757     FUNC(get_tick_count)
2758     FUNC(get_tv96)
2759     FUNC(get_user_av_id)
2760     FUNC(get_user_av96)
2761     FUNC(get_user_tv_id)
2762     FUNC(get_user_tv96)
2763     FUNC(get_vbatt)
2764     FUNC(get_zoom)
2765     FUNC(get_exp_count)
2766     FUNC(get_image_dir)
2767     FUNC(get_flash_params_count)
2768     FUNC(get_parameter_data)
2769     FUNC(get_min_av96)
2770     FUNC(get_max_av96)
2771     FUNC(get_nd_value_ev96)
2772     FUNC(get_nd_current_ev96)
2773     FUNC(get_current_av96)
2774     FUNC(get_current_tv96)
2775     FUNC(get_imager_active)
2776 
2777     FUNC(set_av96_direct)
2778     FUNC(set_av96)
2779     FUNC(set_focus)
2780     FUNC(set_focus_interlock_bypass)
2781     FUNC(set_iso_mode)
2782     FUNC(set_iso_real)
2783     FUNC(set_led)
2784     FUNC(set_nd_filter)
2785     FUNC(set_prop)
2786     FUNC(set_prop_str)
2787     FUNC(set_raw_nr)
2788     FUNC(set_raw)
2789     FUNC(set_sv96)
2790     FUNC(set_tv96_direct)
2791     FUNC(set_tv96)
2792     FUNC(set_user_av_by_id_rel)
2793     FUNC(set_user_av_by_id)
2794     FUNC(set_user_av96)
2795     FUNC(set_user_tv_by_id_rel)
2796     FUNC(set_user_tv_by_id)
2797     FUNC(set_user_tv96)
2798     FUNC(set_zoom_speed)
2799     FUNC(set_zoom_rel)
2800     FUNC(set_zoom)
2801 
2802     FUNC(wait_click)
2803     FUNC(is_pressed)
2804     FUNC(is_key)
2805     FUNC(set_exit_key)
2806     FUNC(wheel_right)
2807     FUNC(wheel_left)
2808     FUNC(md_get_cell_diff)
2809     FUNC(md_get_cell_val)
2810     FUNC(md_detect_motion)
2811     FUNC(md_af_led_control)
2812     FUNC(autostarted)
2813     FUNC(get_autostart)
2814     FUNC(set_autostart)
2815     FUNC(get_usb_power)
2816     FUNC(set_remote_timing)
2817     FUNC(usb_force_active)
2818     FUNC(usb_sync_wait)
2819     FUNC(enter_alt)
2820     FUNC(exit_alt)
2821     FUNC(get_alt_mode)
2822     FUNC(shut_down)
2823     FUNC(print_screen)
2824 
2825     FUNC(get_partitionInfo)
2826     FUNC(swap_partitions)
2827 
2828     FUNC(get_focus_mode)
2829     FUNC(get_focus_state)
2830     FUNC(get_focus_ok)
2831     FUNC(get_propset)
2832     FUNC(get_zoom_steps)
2833     FUNC(get_drive_mode)
2834     FUNC(get_flash_mode)
2835     FUNC(get_shooting)
2836     FUNC(get_flash_ready)
2837     FUNC(get_IS_mode)
2838     FUNC(set_ev)
2839     FUNC(get_ev)
2840     FUNC(get_orientation_sensor)
2841     FUNC(get_nd_present)
2842     FUNC(get_movie_status)
2843     FUNC(set_movie_status)
2844     FUNC(get_video_button)
2845     FUNC(get_video_recording)
2846  
2847     FUNC(get_histo_range)
2848     FUNC(shot_histo_enable)
2849     FUNC(shot_histo_write_to_file)
2850     FUNC(get_live_histo)
2851     FUNC(play_sound)
2852     FUNC(get_temperature)
2853     FUNC(peek)
2854     FUNC(poke)
2855     FUNC(bitand)
2856     FUNC(bitor)
2857     FUNC(bitxor)
2858     FUNC(bitshl)
2859     FUNC(bitshri)
2860     FUNC(bitshru)
2861     FUNC(bitnot)
2862 
2863     FUNC(get_time)
2864 
2865     FUNC(get_buildinfo)
2866     FUNC(get_mode)
2867 
2868     FUNC(set_raw_develop)
2869     // NOTE these functions normally run in the spytask.
2870     // called from lua they will run from kbd task instead
2871     FUNC(raw_merge_start)
2872     FUNC(raw_merge_add_file)
2873     FUNC(raw_merge_end)
2874     FUNC(set_backlight)
2875     FUNC(set_lcd_display)
2876     FUNC(set_draw_title_line)
2877     FUNC(get_draw_title_line)
2878     FUNC(set_aelock)
2879     FUNC(set_aflock)
2880     FUNC(set_mf)
2881     FUNC(get_sd_over_modes)
2882     FUNC(set_curve_state)
2883     FUNC(get_curve_state)
2884     FUNC(set_curve_file)
2885     FUNC(get_curve_file)
2886     // get levent definition by name or id, nil if not found
2887     FUNC(get_levent_def)
2888     // get levent definition by index, nil if out of range
2889     FUNC(get_levent_def_by_index)
2890     // get levent index from name or ID
2891     FUNC(get_levent_index)
2892     FUNC(post_levent_to_ui)
2893     FUNC(post_levent_for_npt)
2894     FUNC(set_levent_active)
2895     FUNC(set_levent_script_mode)
2896 
2897     FUNC(set_capture_mode)
2898     FUNC(set_capture_mode_canon)
2899     FUNC(is_capture_mode_valid)
2900 
2901     FUNC(set_record)
2902 
2903     FUNC(switch_mode_usb)
2904 
2905     FUNC(call_event_proc)
2906     FUNC(call_func_ptr)
2907     FUNC(reboot)
2908     FUNC(get_config_value)
2909     FUNC(set_config_value)
2910     FUNC(set_config_autosave)
2911     FUNC(save_config_file)
2912     FUNC(load_config_file)
2913     FUNC(set_file_attributes)
2914     FUNC(get_meminfo)
2915     FUNC(file_browser)
2916     FUNC(textbox)
2917     FUNC(draw_pixel)
2918     FUNC(draw_line)
2919     FUNC(draw_rect)
2920     FUNC(draw_rect_filled)
2921     FUNC(draw_ellipse)
2922     FUNC(draw_ellipse_filled)
2923     FUNC(draw_clear)
2924     FUNC(draw_string)
2925 
2926     FUNC(get_gui_screen_width)
2927     FUNC(get_gui_screen_height)
2928 
2929     FUNC(set_yield)
2930     FUNC(read_usb_msg)
2931     FUNC(write_usb_msg)
2932     FUNC(get_usb_capture_support)
2933     FUNC(init_usb_capture)
2934     FUNC(get_usb_capture_target)
2935     FUNC(set_usb_capture_timeout)
2936 
2937     FUNC(iso_to_sv96)
2938     FUNC(sv96_to_iso)
2939     FUNC(iso_real_to_market)
2940     FUNC(iso_market_to_real)
2941     FUNC(sv96_real_to_market)
2942     FUNC(sv96_market_to_real)
2943     FUNC(aperture_to_av96)
2944     FUNC(av96_to_aperture)
2945     FUNC(usec_to_tv96)
2946     FUNC(tv96_to_usec)
2947     FUNC(seconds_to_tv96)
2948 
2949     {NULL, NULL},
2950 };
2951 
2952 void register_shoot_hook_fn(lua_State* L, int hook, void *hook_fn, const char *name)
2953 {
2954     lua_pushnumber( L, hook );
2955     lua_pushcclosure( L, hook_fn, 1 );
2956     lua_setfield( L, -2, name);
2957 }
2958 
2959 void register_shoot_hooks( lua_State* L )
2960 {
2961     int i;
2962     for(i=0; i<SCRIPT_NUM_SHOOT_HOOKS;i++) {
2963         lua_createtable(L, 0, 4);
2964         register_shoot_hook_fn(L,i,luaCB_shoot_hook_set,"set");
2965 //        register_shoot_hook_fn(L,i,luaCB_shoot_hook_wait_ready,"wait_ready");
2966         register_shoot_hook_fn(L,i,luaCB_shoot_hook_is_ready,"is_ready");
2967         register_shoot_hook_fn(L,i,luaCB_shoot_hook_continue,"continue");
2968         register_shoot_hook_fn(L,i,luaCB_shoot_hook_count,"count");
2969         lua_setglobal( L, shoot_hook_names[i] );
2970     }
2971 }
2972 
2973 void register_lua_funcs( lua_State* L )
2974 {
2975   const luaL_reg *r;
2976 
2977   register_shoot_hooks( L );
2978   luaopen_rawop( L );
2979 
2980   lua_pushlightuserdata( L, action_push_click );
2981   lua_pushcclosure( L, luaCB_keyfunc, 1 );
2982   lua_setglobal( L, "click" );
2983 
2984   lua_pushlightuserdata( L, action_push_press );
2985   lua_pushcclosure( L, luaCB_keyfunc, 1 );
2986   lua_setglobal( L, "press" );
2987 
2988   lua_pushlightuserdata( L, action_push_release );
2989   lua_pushcclosure( L, luaCB_keyfunc, 1 );
2990   lua_setglobal( L, "release" );
2991 
2992   for(r=chdk_funcs;r->name;r++) {
2993     lua_pushcfunction( L, r->func );
2994     lua_setglobal( L, r->name );
2995   }
2996    luaL_dostring(L,"function usb_msg_table_to_string(t)"
2997                     " local v2s=function(v)"
2998                         " local t=type(v)"
2999                         " if t=='string' then return v end"
3000                         " if t=='number' or t=='boolean' or t=='nil' then return tostring(v) end"
3001                         " return '' end"
3002                     " local r=''"
3003                     " for k,v in pairs(t) do"
3004                         " local s,vs=''"
3005                         " if type(v)=='table' then"
3006                             " for i=1,table.maxn(v) do"
3007                             " s=s..'\\t'..v2s(v[i]) end"
3008                         " else"
3009                             " vs=v2s(v)"
3010                             " if #vs then s=s..'\\t'..vs end"
3011                         " end"
3012                         " vs=v2s(k)"
3013                         " if #vs>0 and #s>0 then r=r..vs..s..'\\n' end"
3014                     " end"
3015                     " return r"
3016                    " end");
3017 
3018 }
3019 
3020 // =========  MODULE INIT =================
3021 
3022 /***************** BEGIN OF AUXILARY PART *********************
3023   ATTENTION: DO NOT REMOVE OR CHANGE SIGNATURES IN THIS SECTION
3024  **************************************************************/
3025 
3026 static void lua_set_variable(char *name, int value, int isBool, int isTable, int labelCount, const char **labels)
3027 {
3028     lua_pushstring( L, name );
3029     if (isTable)
3030     {
3031         lua_createtable(L, labelCount, 2);
3032         int i;
3033         for (i=0; i<labelCount; i++)
3034         {
3035             lua_pushstring(L,labels[i]);
3036             lua_rawseti(L,-2,i+1);
3037         }
3038         SET_INT_FIELD("index", value+1);        // Make value 1 based for Lua table index
3039         SET_STR_FIELD("value", labels[value]);
3040     }
3041     else
3042     {
3043         if (isBool)
3044             lua_pushboolean( L, value );
3045         else
3046             lua_pushnumber( L, value );
3047     }
3048     lua_settable( L, LUA_GLOBALSINDEX );
3049 }
3050 
3051 static void lua_set_as_ret(int md_ret)                  { lua_pushnumber(Lt,md_ret); }
3052 
3053 /******************** Module Information structure ******************/
3054 
3055 libscriptapi_sym _liblua =
3056 {
3057     {
3058          0, 0, 0, 0, 0
3059     },
3060 
3061     lua_script_start,
3062     lua_script_start_file,
3063     lua_script_run,
3064     lua_script_reset,
3065     lua_set_variable,
3066     lua_set_as_ret,
3067     lua_run_restore,
3068     script_shoot_hook_run,
3069 };
3070 
3071 ModuleInfo _module_info =
3072 {
3073     MODULEINFO_V1_MAGICNUM,
3074     sizeof(ModuleInfo),
3075     SCRIPT_API_VERSION,         // Module version
3076 
3077     ANY_CHDK_BRANCH, 0, OPT_ARCHITECTURE,   // Requirements of CHDK version
3078     ANY_PLATFORM_ALLOWED,       // Specify platform dependency
3079 
3080     -LANG_MODULE_LUA,           // Module name
3081     MTYPE_SCRIPT_LANG,          //Run Lua Scripts
3082 
3083     &_liblua.base,
3084 
3085     CONF_VERSION,               // CONF version
3086     CAM_SCREEN_VERSION,         // CAM SCREEN version
3087     CAM_SENSOR_VERSION,         // CAM SENSOR version
3088     CAM_INFO_VERSION,           // CAM INFO version
3089 };
3090 
3091 /*************** END OF AUXILARY PART *******************/

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