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_canon_image_format
  66. luaCB_get_canon_raw_support
  67. luaCB_get_user_tv_id
  68. luaCB_get_user_tv96
  69. luaCB_get_vbatt
  70. luaCB_get_zoom
  71. luaCB_get_parameter_data
  72. luaCB_get_flash_params_count
  73. luaCB_set_av96_direct
  74. luaCB_set_av96
  75. luaCB_set_canon_image_format
  76. luaCB_set_focus_interlock_bypass
  77. luaCB_set_focus
  78. luaCB_set_iso_mode
  79. luaCB_set_iso_real
  80. luaCB_set_led
  81. luaCB_set_nd_filter
  82. luaCB_set_prop
  83. luaCB_set_prop_str
  84. luaCB_set_raw_nr
  85. luaCB_get_raw_nr
  86. luaCB_set_raw
  87. luaCB_get_raw
  88. luaCB_set_sv96
  89. luaCB_set_tv96_direct
  90. luaCB_set_tv96
  91. luaCB_set_user_av_by_id_rel
  92. luaCB_set_user_av_by_id
  93. luaCB_set_user_av96
  94. luaCB_set_user_tv_by_id_rel
  95. luaCB_set_user_tv_by_id
  96. luaCB_set_user_tv96
  97. luaCB_set_zoom_speed
  98. luaCB_set_zoom_rel
  99. luaCB_set_zoom
  100. action_stack_AS_LUA_WAIT_CLICK
  101. luaCB_wait_click
  102. luaCB_is_pressed
  103. luaCB_is_key
  104. luaCB_set_exit_key
  105. luaCB_wheel_right
  106. luaCB_wheel_left
  107. luaCB_md_af_led_control
  108. luaCB_md_get_cell_diff
  109. luaCB_md_get_cell_val
  110. luaCB_md_detect_motion
  111. return_string_selected
  112. action_stack_AS_WAIT_MODULE
  113. luaCB_file_browser
  114. luaCB_textbox
  115. luaCB_draw_pixel
  116. luaCB_draw_line
  117. luaCB_draw_rect
  118. luaCB_draw_rect_filled
  119. luaCB_draw_ellipse
  120. luaCB_draw_ellipse_filled
  121. luaCB_draw_string
  122. luaCB_draw_clear
  123. luaCB_get_gui_screen_width
  124. luaCB_get_gui_screen_height
  125. luaCB_autostarted
  126. luaCB_get_autostart
  127. luaCB_set_autostart
  128. luaCB_get_usb_power
  129. luaCB_set_remote_timing
  130. luaCB_usb_force_active
  131. luaCB_usb_sync_wait
  132. luaCB_enter_alt
  133. luaCB_exit_alt
  134. luaCB_get_alt_mode
  135. luaCB_shut_down
  136. luaCB_print_screen
  137. luaCB_get_movie_status
  138. luaCB_set_movie_status
  139. luaCB_get_video_button
  140. luaCB_get_video_recording
  141. luaCB_get_drive_mode
  142. luaCB_get_focus_mode
  143. luaCB_get_focus_state
  144. luaCB_get_focus_ok
  145. luaCB_get_flash_mode
  146. luaCB_get_shooting
  147. luaCB_get_flash_ready
  148. luaCB_get_IS_mode
  149. luaCB_get_orientation_sensor
  150. luaCB_get_zoom_steps
  151. luaCB_get_nd_present
  152. luaCB_get_propset
  153. luaCB_get_ev
  154. luaCB_set_ev
  155. luaCB_get_histo_range
  156. luaCB_shot_histo_enable
  157. luaCB_shot_histo_write_to_file
  158. luaCB_get_live_histo
  159. luaCB_play_sound
  160. luaCB_get_temperature
  161. luaCB_get_time
  162. luaCB_set_clock
  163. luaCB_peek
  164. luaCB_poke
  165. luaCB_bitand
  166. luaCB_bitor
  167. luaCB_bitxor
  168. luaCB_bitshl
  169. luaCB_bitshri
  170. luaCB_bitshru
  171. luaCB_bitnot
  172. set_string_field
  173. set_number_field
  174. luaCB_get_buildinfo
  175. luaCB_get_mode
  176. luaCB_set_raw_develop
  177. luaCB_raw_merge_start
  178. luaCB_raw_merge_add_file
  179. luaCB_raw_merge_end
  180. luaCB_set_backlight
  181. luaCB_set_lcd_display
  182. luaCB_set_draw_title_line
  183. luaCB_get_draw_title_line
  184. levent_id_from_lua_arg
  185. levent_index_from_id_lua_arg
  186. luaCB_get_levent_def
  187. luaCB_get_levent_index
  188. luaCB_get_levent_def_by_index
  189. luaCB_post_levent_to_ui
  190. luaCB_post_levent_for_npt
  191. luaCB_set_levent_active
  192. luaCB_set_levent_script_mode
  193. luaCB_set_capture_mode_canon
  194. luaCB_set_capture_mode
  195. luaCB_is_capture_mode_valid
  196. luaCB_set_record
  197. luaCB_switch_mode_usb
  198. luaCB_force_analog_av
  199. pack_native_args
  200. luaCB_call_func_ptr
  201. luaCB_call_event_proc
  202. luaCB_reboot
  203. luaCB_get_config_value
  204. luaCB_set_config_value
  205. luaCB_set_config_autosave
  206. luaCB_save_config_file
  207. luaCB_load_config_file
  208. luaCB_set_file_attributes
  209. action_stack_AS_SCRIPT_READ_USB_MSG
  210. action_stack_AS_SCRIPT_WRITE_USB_MSG
  211. luaCB_read_usb_msg
  212. luaCB_write_usb_msg
  213. set_meminfo_num
  214. luaCB_get_meminfo
  215. luaCB_set_yield
  216. luaCB_get_usb_capture_support
  217. luaCB_init_usb_capture
  218. luaCB_get_usb_capture_target
  219. luaCB_set_usb_capture_timeout
  220. luaCB_iso_to_sv96
  221. luaCB_sv96_to_iso
  222. luaCB_iso_real_to_market
  223. luaCB_iso_market_to_real
  224. luaCB_sv96_real_to_market
  225. luaCB_sv96_market_to_real
  226. luaCB_aperture_to_av96
  227. luaCB_av96_to_aperture
  228. luaCB_usec_to_tv96
  229. luaCB_tv96_to_usec
  230. luaCB_seconds_to_tv96
  231. luaCB_shoot_hook_set
  232. luaCB_shoot_hook_is_ready
  233. luaCB_shoot_hook_continue
  234. luaCB_shoot_hook_count
  235. register_shoot_hook_fn
  236. register_shoot_hooks
  237. register_lua_funcs
  238. lua_set_variable
  239. lua_set_as_ret

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

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