source: branches/reyalp-flt/core/luascript.c @ 1513

Revision 1513, 66.2 KB checked in by philmoz, 2 years ago (diff)

Cleanup of code for handling CHDK 'gui' mode.

  • Property svn:eol-style set to native
Line 
1#include "luascript.h"
2#include "kbd.h"
3#include "platform.h"
4#include "script.h"
5#include "lua.h"
6#include "lualib.h"
7#include "lauxlib.h"
8#include "conf.h"
9#include "shot_histogram.h"
10#include "stdlib.h"
11#include "raw.h"
12#include "modules.h"
13#include "levent.h"
14#include "console.h"
15#include "action_stack.h"
16#include "motion_detector.h"
17#include "ptp.h"
18#include "core.h"
19#include "gui_fselect.h"
20#include "lang.h"
21#include "gui_lang.h"
22#include "gui_draw.h"
23
24#include "../lib/lua/lstate.h"  // for L->nCcalls, baseCcalls
25
26lua_State* L;
27lua_State* Lt;
28
29static int lua_script_is_ptp;
30static int run_first_resume; // 1 first 'resume', 0 = resuming from yield
31static int run_start_tick; // tick count at start of this kbd_task iteration
32static int run_hook_count; // number of calls to the count hook this kbd_task iteration
33#define YIELD_CHECK_COUNT 100 // check for yield every N vm instructions
34#define YIELD_MAX_COUNT_DEFAULT 25 // 25 checks = 2500 vm instructions
35#define YIELD_MAX_MS_DEFAULT 10
36static unsigned yield_max_count;
37static unsigned yield_max_ms;
38static int yield_hook_enabled;
39
40static void lua_script_disable_yield_hook(void) {
41    yield_hook_enabled = 0;
42}
43static void lua_script_enable_yield_hook(void) {
44    yield_hook_enabled = 1;
45}
46
47#ifdef CAM_CHDK_PTP
48// create a ptp message from the given stack index
49// incompatible types will return a TYPE_UNSUPPORTED message
50static ptp_script_msg *lua_create_usb_msg( lua_State* L, int index, unsigned msgtype) {
51    // TODO maybe we should just pass the lua type constants
52    unsigned datatype, datasize = 4;
53    int ivalue = 0;
54    void *data = &ivalue;
55    int ltype = lua_type(L,index);
56    switch(ltype) {
57        case LUA_TNONE:
58            return NULL; // nothing on the stack, no message generated
59        break;
60        case LUA_TNIL:
61            datatype = PTP_CHDK_TYPE_NIL;
62        break;
63        case LUA_TBOOLEAN:
64            datatype = PTP_CHDK_TYPE_BOOLEAN;
65            ivalue = lua_toboolean(L,index);
66        break;
67        case LUA_TNUMBER:
68            datatype = PTP_CHDK_TYPE_INTEGER;
69            ivalue = lua_tonumber(L,index);
70        break;
71        case LUA_TSTRING:
72            datatype = PTP_CHDK_TYPE_STRING;
73            data = (char *)lua_tolstring(L,index,&datasize);
74        break;
75        // TODO this uses usb_msg_table_to_string to serialize the table
76        // the default format is described in
77        // http://chdk.setepontos.com/index.php?topic=4338.msg62606#msg62606
78        // other formats can be implemented by overriding this function in your lua code
79        case LUA_TTABLE: {
80            int result;
81            lua_script_disable_yield_hook(); // don't want to yield while converting
82            lua_getglobal(L, "usb_msg_table_to_string"); // push function
83            lua_pushvalue(L, index); // copy specified index to top of stack
84            result = lua_pcall(L,1,1,0); // this will leave an error message as a string on the stack if call fails
85            lua_script_enable_yield_hook();
86            if( result ) {
87                // if called from lua, throw a normal error
88                if( msgtype == PTP_CHDK_S_MSGTYPE_USER ) {
89                    luaL_error(L,lua_tostring(L,-1));
90                    return NULL; // not reached
91                } else { // if it's a return, convert the message to an ERR
92                    msgtype = PTP_CHDK_S_MSGTYPE_ERR;
93                    datatype = PTP_CHDK_S_ERRTYPE_RUN;
94                    data = (char *)lua_tolstring(L,-1,&datasize);
95                    break;
96                }
97            }
98            // an empty table is returned as an empty string by default
99            // a non-string should never show up here
100            if ( !lua_isstring(L,-1) ) {
101                return NULL;
102            }
103            datatype = PTP_CHDK_TYPE_TABLE;
104            data = (char *)lua_tolstring(L,-1,&datasize);
105            lua_pop(L,1);
106        }
107        break;
108        default:
109            datatype = PTP_CHDK_TYPE_UNSUPPORTED;
110            data = (char *)lua_typename(L,ltype); // return type name as message data
111            datasize = strlen(data);
112    }
113    return ptp_script_create_msg(msgtype,datatype,datasize,data);
114}
115
116void lua_script_error_ptp(int runtime, const char *err) {
117    if(runtime) {
118        ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, err);
119        script_end();
120    } else {
121        ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_COMPILE, err);
122        lua_script_reset();
123    }
124}
125#endif
126
127void lua_script_reset()
128{
129  module_rawop_unload();
130  lua_close( L );
131  L = 0;
132}
133
134static void lua_count_hook(lua_State *L, lua_Debug *ar)
135{
136  run_hook_count++;
137  if( L->nCcalls > L->baseCcalls || !yield_hook_enabled )
138    return;
139  if(run_hook_count >= yield_max_count || get_tick_count() - run_start_tick >= yield_max_ms)
140    lua_yield( L, 0 );
141}
142
143void lua_script_error(lua_State *Lt,int runtime)
144{
145    const char *err = lua_tostring( Lt, -1 );
146    script_console_add_line( err );
147    if(lua_script_is_ptp) {
148#ifdef CAM_CHDK_PTP
149        lua_script_error_ptp(runtime,err);
150#endif
151    } else {
152        if(runtime) {
153            if(conf.debug_lua_restart_on_error) {
154                lua_script_reset();
155                script_start_gui(0);
156            } else {
157                script_wait_and_end();
158            }
159        } else {
160            script_print_screen_end();
161            script_wait_and_end();
162        }
163    }
164}
165
166
167// TODO more stuff from script.c should be moved here
168void lua_script_finish(lua_State *L)
169{
170#ifdef CAM_CHDK_PTP
171    if(lua_script_is_ptp) {
172        // send all return values as RET messages
173        int i,end = lua_gettop(L);
174        for(i=1;i<=end; i++) {
175            ptp_script_msg *msg = lua_create_usb_msg(L,i,PTP_CHDK_S_MSGTYPE_RET);
176            // if the queue is full return values will be silently discarded
177            // incompatible types will be returned as TYPE_UNSUPPORTED to preserve expected number and order of return values
178            if(msg) {
179                ptp_script_write_msg(msg);
180                // create_usb_msg may convert the message to an error
181                if(msg->type != PTP_CHDK_S_MSGTYPE_RET) {
182                    break;
183                }
184            } else {
185                ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, "error creating return msg");
186                break;
187            }
188        }
189    }
190#endif
191}
192
193int lua_script_start( char const* script, int ptp )
194{
195  lua_script_is_ptp = ptp;
196  L = lua_open();
197  luaL_openlibs( L );
198  register_lua_funcs( L );
199
200  Lt = lua_newthread( L );
201  lua_setfield( L, LUA_REGISTRYINDEX, "Lt" );
202  if( luaL_loadstring( Lt, script ) != 0 ) {
203    lua_script_error(Lt,0);
204    return 0;
205  }
206  lua_sethook(Lt, lua_count_hook, LUA_MASKCOUNT, YIELD_CHECK_COUNT );
207  lua_script_enable_yield_hook();
208  run_first_resume = 1;
209  yield_max_count = YIELD_MAX_COUNT_DEFAULT;
210  yield_max_ms = YIELD_MAX_MS_DEFAULT;
211  return 1;
212}
213
214// run a timeslice of lua script
215void lua_script_run(void)
216{
217    int Lres;
218    int top;
219    if (run_first_resume) {
220        run_first_resume = 0;
221        top = 0;
222    } else {
223        top = lua_gettop(Lt);
224    }
225    run_start_tick = get_tick_count();
226    run_hook_count = 0;
227    Lres = lua_resume( Lt, top );
228
229    if (Lres == LUA_YIELD) {
230        // yielded
231        return;
232    } else if(Lres != 0) {
233        lua_script_error(Lt,1);
234        return;
235    } else {
236        // finished normally, add ptp result
237        lua_script_finish(Lt);
238        script_console_add_line(lang_str(LANG_CONSOLE_TEXT_FINISHED));
239        action_pop();
240        script_end();
241    }
242}
243
244// run the "restore" function at the end of a script
245void lua_run_restore()
246{
247        lua_getglobal(Lt, "restore");
248        if (lua_isfunction(Lt, -1)) {
249                if (lua_pcall( Lt, 0, 0, 0 )) {
250                        script_console_add_line( lua_tostring( Lt, -1 ) );
251                }
252        }
253}
254
255// get key ID of key name at arg, throw error if invalid
256static int lua_get_key_arg( lua_State * L, int narg )
257{
258    int k = script_keyid_by_name( luaL_checkstring( L, narg ) );
259    if(!k)
260        luaL_error( L, "unknown key" );
261    return k;
262}
263
264#ifdef OPT_CURVES
265#include "curves.h"
266
267static int luaCB_set_curve_state( lua_State* L )
268{
269  int value;
270  value=luaL_checknumber( L, 1 );
271  if (module_curves_load())
272    return luaL_argerror(L,1,"fail to load curves module");
273  curve_set_mode(value);
274  return 0;
275}
276#endif
277
278static int luaCB_set_aflock(lua_State* L)
279{
280  int val = luaL_checknumber(L, 1);
281  if (val>0) DoAFLock();  // 1: enable AFLock
282  else UnlockAF();       // 0: disable unlock AF
283  return 0;
284}
285
286
287static int luaCB_shoot( lua_State* L )
288{
289  action_push(AS_SHOOT);
290  return lua_yield( L, 0 );
291}
292
293static int luaCB_sleep( lua_State* L )
294{
295  action_push_delay( luaL_checknumber( L, 1 ) );
296  return lua_yield( L, 0 );
297}
298
299// for press,release and click
300static int luaCB_keyfunc( lua_State* L )
301{
302  void* func = lua_touserdata( L, lua_upvalueindex(1) );
303  ((void(*)(long))func)( lua_get_key_arg( L, 1 ) );
304  return lua_yield( L, 0 );
305}
306
307static int luaCB_cls( lua_State* L )
308{
309  console_clear();
310  return 0;
311}
312
313static int luaCB_set_console_layout( lua_State* L )
314{
315  console_set_layout(luaL_checknumber( L, 1 ),luaL_checknumber( L, 2 ),luaL_checknumber( L, 3 ),luaL_checknumber( L, 4 ));
316  return 0;
317}
318
319static int luaCB_set_console_autoredraw( lua_State* L )
320{
321  console_set_autoredraw(luaL_checknumber(L,1));
322  return 0;
323}
324
325static int luaCB_console_redraw( lua_State* L )
326{
327  console_redraw();
328  return 0;
329}
330static int luaCB_get_av96( lua_State* L )
331{
332  lua_pushnumber( L, shooting_get_av96() );
333  return 1;
334}
335
336static int luaCB_get_bv96( lua_State* L )
337{
338  lua_pushnumber( L, shooting_get_bv96() );
339  return 1;
340}
341
342static int luaCB_get_day_seconds( lua_State* L )
343{
344  lua_pushnumber( L, shooting_get_day_seconds() );
345  return 1;
346}
347
348static int luaCB_get_disk_size( lua_State* L )
349{
350  lua_pushnumber( L, GetTotalCardSpaceKb() );
351  return 1;
352}
353
354static int luaCB_get_dof( lua_State* L )
355{
356  lua_pushnumber( L, shooting_get_depth_of_field() );
357  return 1;
358}
359
360static int luaCB_get_far_limit( lua_State* L )
361{
362  lua_pushnumber( L, shooting_get_far_limit_of_acceptable_sharpness() );
363  return 1;
364}
365
366static int luaCB_get_free_disk_space( lua_State* L )
367{
368  lua_pushnumber( L, GetFreeCardSpaceKb() );
369  return 1;
370}
371
372static int luaCB_get_focus( lua_State* L )
373{
374  lua_pushnumber( L, shooting_get_subject_distance() );
375  return 1;
376}
377
378static int luaCB_get_hyp_dist( lua_State* L )
379{
380  lua_pushnumber( L, shooting_get_hyperfocal_distance() );
381  return 1;
382}
383
384static int luaCB_get_iso_market( lua_State* L )
385{
386  lua_pushnumber( L, shooting_get_iso_market() );
387  return 1;
388}
389
390static int luaCB_get_iso_mode( lua_State* L )
391{
392  lua_pushnumber( L, shooting_get_iso_mode() );
393  return 1;
394}
395
396static int luaCB_get_iso_real( lua_State* L )
397{
398  lua_pushnumber( L, shooting_get_iso_real() );
399  return 1;
400}
401
402static int luaCB_get_jpg_count( lua_State* L )
403{
404  lua_pushnumber( L, GetJpgCount() );
405  return 1;
406}
407
408static int luaCB_get_near_limit( lua_State* L )
409{
410  lua_pushnumber( L, shooting_get_near_limit_of_acceptable_sharpness() );
411  return 1;
412}
413
414/*
415val=get_prop(id)
416get propcase value identified by id
417the propcase is read as a short and sign extended to an int
418*/
419static int luaCB_get_prop( lua_State* L )
420{
421  lua_pushnumber( L, shooting_get_prop( luaL_checknumber( L, 1 ) ) );
422  return 1;
423}
424
425/*
426val=get_prop_str(prop_id,length)
427get the value of a propertycase as a string
428numeric values may be extracted using string.byte or or the binstr.lua module
429returns the value as a string, or false if the underlying propcase call returned non-zero
430*/
431static int luaCB_get_prop_str( lua_State* L ) {
432    void *buf;
433    unsigned size;
434    unsigned prop_id = luaL_checknumber( L, 1 );
435    size = luaL_checknumber( L, 2 );
436    buf = malloc(size);
437    if(!buf) {
438        return luaL_error( L, "malloc failed in luaCB_get_prop" );
439    }
440    if(get_property_case(prop_id,buf,size) == 0) {
441        lua_pushlstring( L, buf, size );
442    } else {
443        lua_pushboolean( L, 0);
444    }
445    free(buf);
446    return 1;
447}
448
449static int luaCB_get_raw_count( lua_State* L )
450{
451  lua_pushnumber( L, GetRawCount() );
452  return 1;
453}
454
455static int luaCB_get_sv96( lua_State* L )
456{
457  lua_pushnumber( L, shooting_get_sv96() );
458  return 1;
459}
460
461static int luaCB_get_tick_count( lua_State* L )
462{
463  lua_pushnumber( L, shooting_get_tick_count() );
464  return 1;
465}
466
467static int luaCB_get_exp_count( lua_State* L )
468{
469  lua_pushnumber( L, get_exposure_counter() );
470  return 1;
471}
472
473static int luaCB_get_tv96( lua_State* L )
474{
475  lua_pushnumber( L, shooting_get_tv96() );
476  return 1;
477}
478
479static int luaCB_get_user_av_id( lua_State* L )
480{
481  lua_pushnumber( L, shooting_get_user_av_id() );
482  return 1;
483}
484
485static int luaCB_get_user_av96( lua_State* L )
486{
487  lua_pushnumber( L, shooting_get_user_av96() );
488  return 1;
489}
490
491static int luaCB_get_user_tv_id( lua_State* L )
492{
493  lua_pushnumber( L, shooting_get_user_tv_id() );
494  return 1;
495}
496
497static int luaCB_get_user_tv96( lua_State* L )
498{
499  lua_pushnumber( L, shooting_get_user_tv96() );
500  return 1;
501}
502
503static int luaCB_get_vbatt( lua_State* L )
504{
505  lua_pushnumber( L, stat_get_vbatt() );
506  return 1;
507}
508
509static int luaCB_get_zoom( lua_State* L )
510{
511  lua_pushnumber( L, shooting_get_zoom() );
512  return 1;
513}
514
515static int luaCB_get_parameter_data( lua_State* L )
516{
517  extern long* FlashParamsTable[];
518
519  unsigned size;
520  unsigned id = luaL_checknumber( L, 1 );
521  unsigned val;
522
523  if (id >= get_flash_params_count()) {
524    // return nil
525    return 0;
526  }
527
528  size = FlashParamsTable[id][1]>>16;
529  if (size == 0) {
530    // return nil
531    return 0;
532  }
533  if (size >= 1 && size <= 4) {
534    val = 0;
535    get_parameter_data( id, &val, size );
536    lua_pushlstring( L, (char *)&val, size );
537    // for convenience, params that fit in a number are returned in one as a second result
538    lua_pushnumber( L, val );
539    return 2;
540  }
541  else {
542    char *buf = malloc(size);
543    if(!buf) {
544      luaL_error( L, "malloc failed in luaCB_get_parameter_data" );
545    }
546    get_parameter_data( id, buf, size );
547    lua_pushlstring( L, buf, size );
548    free(buf);
549    return 1;
550  }
551}
552
553static int luaCB_get_flash_params_count( lua_State* L )
554{
555  lua_pushnumber( L, get_flash_params_count() );
556  return 1;
557}
558
559static int luaCB_set_av96_direct( lua_State* L )
560{
561  shooting_set_av96_direct( luaL_checknumber( L, 1 ), SET_LATER );
562  return 0;
563}
564
565static int luaCB_set_av96( lua_State* L )
566{
567  shooting_set_av96( luaL_checknumber( L, 1 ), SET_LATER );
568  return 0;
569}
570
571static int luaCB_set_focus( lua_State* L )
572{
573    int to = luaL_checknumber( L, 1 );
574    int m=mode_get()&MODE_SHOOTING_MASK;
575    int mode_video=MODE_IS_VIDEO(m);
576
577#if CAM_HAS_MANUAL_FOCUS
578    if (shooting_get_focus_mode() || (mode_video)) shooting_set_focus(to, SET_NOW);
579    else shooting_set_focus(to, SET_LATER);
580#else
581    if (mode_video) shooting_set_focus(to, SET_NOW);
582    else shooting_set_focus(to, SET_LATER);   
583#endif   
584  return 0;
585}
586
587static int luaCB_set_iso_mode( lua_State* L )
588{
589  shooting_set_iso_mode( luaL_checknumber( L, 1 ) );
590  return 0;
591}
592
593static int luaCB_set_iso_real( lua_State* L )
594{
595  shooting_set_iso_real( luaL_checknumber( L, 1 ), SET_LATER);
596  return 0;
597}
598
599static int luaCB_set_led( lua_State* L )
600{
601  int to, to1, to2;
602  to = luaL_checknumber( L, 1 );
603  to1 = luaL_checknumber( L, 2 );
604  to2 = 200;
605  if( lua_isnumber( L, 3 ) )
606    to2 = lua_tonumber( L, 3 );
607  camera_set_led(to, to1, to2);
608  return 0;
609}
610
611static int luaCB_set_nd_filter( lua_State* L )
612{
613  shooting_set_nd_filter_state( luaL_checknumber( L, 1 ), SET_LATER);
614  return 0;
615}
616
617/*
618set_prop(id,value)
619the value is treated as a short
620*/
621static int luaCB_set_prop( lua_State* L )
622{
623  shooting_set_prop(luaL_checknumber( L, 1 ), luaL_checknumber( L, 2 ));
624  return 0;
625}
626
627/*
628status=set_prop_str(prop_id,value)
629set propertycase value as a string. Length is taken from the string
630numeric propcase values may be assembled by setting byte values using string.char or the binstr module
631status: boolean - true if the underlying propcase call returns 0, otherwise false
632*/
633static int luaCB_set_prop_str( lua_State *L ) {
634    int prop_id;
635    unsigned len;
636    const char *str;
637    prop_id = luaL_checknumber( L, 1 );
638    str = luaL_checklstring( L, 2, &len );
639    if(str && len > 0) {
640        lua_pushboolean( L, (set_property_case(prop_id,(void *)str,len) == 0));
641    } else {
642        return luaL_error( L, "invalid value");
643    }
644    return 1;
645}
646
647static int luaCB_set_raw_nr( lua_State* L )
648{
649  camera_set_nr(luaL_checknumber( L, 1 ));
650  return 0;
651}
652
653static int luaCB_get_raw_nr( lua_State* L )
654{
655  lua_pushnumber( L, camera_get_nr() );
656  return 1;
657}
658
659static int luaCB_set_raw( lua_State* L )
660{
661  camera_set_raw(luaL_checknumber( L, 1 ));
662  return 0;
663}
664
665static int luaCB_get_raw( lua_State* L )
666{
667  lua_pushnumber( L, conf.save_raw );
668  return 1;
669}
670
671static int luaCB_set_sv96( lua_State* L )
672{
673  shooting_set_sv96(luaL_checknumber( L, 1 ), SET_LATER);
674  return 0;
675}
676
677static int luaCB_set_tv96_direct( lua_State* L )
678{
679  shooting_set_tv96_direct(luaL_checknumber( L, 1 ), SET_LATER);
680  return 0;
681}
682
683static int luaCB_set_tv96( lua_State* L )
684{
685  shooting_set_tv96(luaL_checknumber( L, 1 ), SET_LATER);
686  return 0;
687}
688
689static int luaCB_set_user_av_by_id_rel( lua_State* L )
690{
691  shooting_set_user_av_by_id_rel(luaL_checknumber( L, 1 ));
692  return 0;
693}
694
695static int luaCB_set_user_av_by_id( lua_State* L )
696{
697  shooting_set_user_av_by_id(luaL_checknumber( L, 1 ));
698  return 0;
699}
700
701static int luaCB_set_user_av96( lua_State* L )
702{
703  shooting_set_user_av96(luaL_checknumber( L, 1 ));
704  return 0;
705}
706
707static int luaCB_set_user_tv_by_id_rel( lua_State* L )
708{
709  shooting_set_user_tv_by_id_rel(luaL_checknumber( L, 1 ));
710  return 0;
711}
712
713static int luaCB_set_user_tv_by_id( lua_State* L )
714{
715  shooting_set_user_tv_by_id(luaL_checknumber( L, 1 ));
716  return 0;
717}
718
719static int luaCB_set_user_tv96( lua_State* L )
720{
721  shooting_set_user_tv96(luaL_checknumber( L, 1 ));
722  return 0;
723}
724
725static int luaCB_set_zoom_speed( lua_State* L )
726{
727  shooting_set_zoom_speed(luaL_checknumber( L, 1 ));
728  return 0;
729}
730
731static int luaCB_set_zoom_rel( lua_State* L )
732{
733  shooting_set_zoom_rel(luaL_checknumber( L, 1 ));
734  return 0;
735}
736
737static int luaCB_set_zoom( lua_State* L )
738{
739  shooting_set_zoom(luaL_checknumber( L, 1 ));
740  return 0;
741}
742
743static int luaCB_wait_click( lua_State* L )
744{
745  int timeout = luaL_optnumber( L, 1, 0 );
746  action_wait_for_click(timeout);
747  return lua_yield( L, 0 );
748}
749
750static int luaCB_is_pressed( lua_State* L )
751{
752  lua_pushboolean( L, script_key_is_pressed(lua_get_key_arg( L, 1 )));
753  return 1;
754}
755
756static int luaCB_is_key( lua_State* L )
757{
758  lua_pushboolean( L, script_key_is_clicked(lua_get_key_arg( L, 1 )));
759  return 1;
760}
761
762#if CAM_HAS_JOGDIAL
763static int luaCB_wheel_right( lua_State* L )
764{
765  JogDial_CW();
766  return 0;
767}
768
769static int luaCB_wheel_left( lua_State* L )
770{
771  JogDial_CCW();
772  return 0;
773}
774#endif
775
776static int luaCB_md_get_cell_diff( lua_State* L )
777{
778  lua_pushnumber( L, md_get_cell_diff(luaL_checknumber(L,1),
779                                      luaL_checknumber(L,2)));
780  return 1;
781}
782
783static int luaCB_md_detect_motion( lua_State* L )
784{
785  int columns = (luaL_optnumber(L,1,6));
786  int rows = (luaL_optnumber(L,2,4));
787  int pixel_measure_mode = (luaL_optnumber(L,3,1));
788  int detection_timeout = (luaL_optnumber(L,4,10000));
789  int measure_interval = (luaL_optnumber(L,5,7));
790  int threshold = (luaL_optnumber(L,6,10));
791  int draw_grid = (luaL_optnumber(L,7,1));
792   // arg 8 is the return value in ubasic. We
793   // ignore it here. - AUJ
794  int clipping_region_mode = (luaL_optnumber(L,9,0));
795  int clipping_region_column1 = (luaL_optnumber(L,10,0));
796  int clipping_region_row1 = (luaL_optnumber(L,11,0));
797  int clipping_region_column2 = (luaL_optnumber(L,12,0));
798  int clipping_region_row2 = (luaL_optnumber(L,13,0));
799  int parameters = (luaL_optnumber(L,14,1));
800  int pixels_step = (luaL_optnumber(L,15,6));
801  int msecs_before_trigger = (luaL_optnumber(L,16,0));
802  if(md_init_motion_detector(
803    columns, rows, pixel_measure_mode, detection_timeout,
804    measure_interval, threshold, draw_grid,
805    clipping_region_mode,
806    clipping_region_column1, clipping_region_row1,
807    clipping_region_column2, clipping_region_row2,
808    parameters, pixels_step, msecs_before_trigger
809  ))
810    return lua_yield(L, 0);
811  else
812    return luaL_error( L, "md_init_motion_detector failed" );
813}
814
815static void file_browser_selected(const char *fn) {
816    // Reconnect button input to script - will also signal action stack
817    // that file browser is finished and return last selected file
818    // to script caller
819    state_kbd_script_run = 1;
820    // Clear the Func/Set key so that when the script exits, pressing
821    // the Func/Set key again will enter the Script menu, not the File Browser
822    kbd_reset_autoclicked_key();
823
824        lua_pushstring( Lt, (fn && fn[0])? fn : NULL );
825
826}
827
828static int luaCB_file_browser( lua_State* L ) {
829    // Disconnect button input from script so buttons will work in file browser
830    state_kbd_script_run = 0;
831    // Push file browser action onto stack - will loop doing nothing until file browser exits
832    action_push(AS_FILE_BROWSER);
833    // Switch to file browser gui mode. Path can be supplied in call or defaults to "A" (root directory).
834    module_fselect_init(LANG_STR_FILE_BROWSER, luaL_optstring( L, 1, "A" ), "A", file_browser_selected);
835    // Yield the script so that the action stack will process the AS_FILE_BROWSER action
836    return lua_yield(L, 0);
837}
838
839unsigned char script_colors[][2]  = {
840
841#ifdef CAM_USE_COLORED_ICONS
842                                        {COLOR_TRANSPARENT,         COLOR_TRANSPARENT},         //  1   trans
843                                        {COLOR_BLACK,               COLOR_BLACK},               //  2   black
844                                        {COLOR_WHITE,               COLOR_WHITE},               //  3   white
845                                       
846                                        {COLOR_ICON_PLY_RED,        COLOR_ICON_REC_RED},        //  4   red
847                                        {COLOR_ICON_PLY_RED_DK,     COLOR_ICON_REC_RED_DK},     //  5   red_dark
848                                        {COLOR_ICON_PLY_RED_LT,     COLOR_ICON_REC_RED_LT},     //  6   red_light
849                                        {COLOR_ICON_PLY_GREEN,      COLOR_ICON_REC_GREEN},      //  7   green
850                                        {COLOR_ICON_PLY_GREEN_DK,   COLOR_ICON_REC_GREEN_DK},   //  8   green_dark
851                                        {COLOR_ICON_PLY_GREEN_LT,   COLOR_ICON_REC_GREEN_LT},   //  9   green_light
852                                        {COLOR_HISTO_B_PLAY,        COLOR_HISTO_B},             //  10  blue
853                                        {COLOR_HISTO_B_PLAY,        COLOR_HISTO_B},             //  11  blue_dark   - placeholder
854                                        {COLOR_HISTO_B_PLAY,        COLOR_HISTO_B},             //  12  blue_light  - placeholder
855
856                                        {COLOR_ICON_PLY_GREY,       COLOR_ICON_REC_GREY},       //  13  grey
857                                        {COLOR_ICON_PLY_GREY_DK,    COLOR_ICON_REC_GREY_DK},    //  14  grey_dark
858                                        {COLOR_ICON_PLY_GREY_LT,    COLOR_ICON_REC_GREY_LT},    //  15  grey_light
859
860                                        {COLOR_ICON_PLY_YELLOW,     COLOR_ICON_REC_YELLOW},     //  16  yellow
861                                        {COLOR_ICON_PLY_YELLOW_DK,  COLOR_ICON_REC_YELLOW_DK},  //  17  yellow_dark
862                                        {COLOR_ICON_PLY_YELLOW_LT,  COLOR_ICON_REC_YELLOW_LT}   //  18  yellow_light
863#else
864                                        {COLOR_TRANSPARENT,         COLOR_TRANSPARENT},         //  1   trans
865                                        {COLOR_BLACK,               COLOR_BLACK},               //  2   black
866                                        {COLOR_WHITE,               COLOR_WHITE},               //  3   white
867                                       
868                                        {COLOR_HISTO_R_PLAY,        COLOR_HISTO_R},             //  4   red
869                                        {COLOR_HISTO_R_PLAY,        COLOR_HISTO_R},             //  5   red_dark    - placeholder
870                                        {COLOR_HISTO_R_PLAY,        COLOR_HISTO_R},             //  6   red_light   - placeholder
871                                        {COLOR_HISTO_G_PLAY,        COLOR_HISTO_G},             //  7   green
872                                        {COLOR_HISTO_G_PLAY,        COLOR_HISTO_G},             //  8   green_dark  - placeholder
873                                        {COLOR_HISTO_G_PLAY,        COLOR_HISTO_G},             //  9   green_light - placeholder
874                                        {COLOR_HISTO_B_PLAY,        COLOR_HISTO_B},             //  10  blue
875                                        {COLOR_HISTO_B_PLAY,        COLOR_HISTO_B},             //  11  blue_dark   - placeholder
876                                        {COLOR_HISTO_B_PLAY,        COLOR_HISTO_B},             //  12  blue_light  - placeholder
877
878                                        {COLOR_BLACK,               COLOR_BLACK},                           //  13  grey        - placeholder (there's no universal grey)
879                                        {COLOR_BLACK,               COLOR_BLACK},                           //  14  grey_dark   - placeholder (there's no universal grey)
880                                        {COLOR_WHITE,               COLOR_WHITE},               //  15  grey_light  - placeholder (there's no universal grey)
881
882                                        {COLOR_WHITE,               COLOR_WHITE},               //  16  yellow      - placeholder
883                                        {COLOR_WHITE,               COLOR_WHITE},               //  17  yellow_dark - placeholder
884                                        {COLOR_WHITE,               COLOR_WHITE}                //  18  yellow_light- placeholder
885#endif
886                                    };
887
888static int get_color(int cl) {
889    char out=0;                     //defaults to 0 if any wrong number
890
891    if (cl<256)
892        out=cl;
893    else {
894        if (cl-256<sizeof(script_colors)) {
895            if((mode_get()&MODE_MASK) == MODE_REC)
896                out=script_colors[cl-256][1];
897            else
898                out=script_colors[cl-256][0];
899        }
900    }
901    return out;
902}
903
904static int luaCB_draw_pixel( lua_State* L ) {
905  coord x1=luaL_checknumber(L,1);
906  coord y1=luaL_checknumber(L,2);
907  color cl=get_color(luaL_checknumber(L,3));
908  draw_pixel(x1,y1,cl);
909  return 1;
910}
911
912static int luaCB_draw_line( lua_State* L ) {
913  coord x1=luaL_checknumber(L,1);
914  coord y1=luaL_checknumber(L,2);
915  coord x2=luaL_checknumber(L,3);
916  coord y2=luaL_checknumber(L,4);
917  color cl=get_color(luaL_checknumber(L,5));
918  draw_line(x1,y1,x2,y2,cl);
919  return 1;
920}
921
922static int luaCB_draw_rect( lua_State* L ) {
923  coord x1=luaL_checknumber(L,1);
924  coord y1=luaL_checknumber(L,2);
925  coord x2=luaL_checknumber(L,3);
926  coord y2=luaL_checknumber(L,4);
927  color cl=get_color(luaL_checknumber(L,5));
928  int   th=luaL_optnumber(L,6,1);
929  draw_rect_thick(x1,y1,x2,y2,cl,th);
930  return 1;
931}
932
933static int luaCB_draw_rect_filled( lua_State* L ) {
934  coord x1 =luaL_checknumber(L,1);
935  coord y1 =luaL_checknumber(L,2);
936  coord x2 =luaL_checknumber(L,3);
937  coord y2 =luaL_checknumber(L,4);
938  color clf=get_color(luaL_checknumber(L,5));
939  color clb=get_color(luaL_checknumber(L,6));
940  int   th =luaL_optnumber(L,7,1);
941  clf=256*clb+clf;
942  draw_filled_rect_thick(x1,y1,x2,y2,clf,th);
943  return 1;
944}
945
946static int luaCB_draw_ellipse( lua_State* L ) {
947  coord x1=luaL_checknumber(L,1);
948  coord y1=luaL_checknumber(L,2);
949  coord a=luaL_checknumber(L,3);
950  coord b=luaL_checknumber(L,4);
951  color cl=get_color(luaL_checknumber(L,5));
952  draw_ellipse(x1,y1,a,b,cl);
953  return 1;
954}
955
956static int luaCB_draw_ellipse_filled( lua_State* L ) {
957  coord x1=luaL_checknumber(L,1);
958  coord y1=luaL_checknumber(L,2);
959  coord a=luaL_checknumber(L,3);
960  coord b=luaL_checknumber(L,4);
961  color cl=256*get_color(luaL_checknumber(L,5));
962  draw_filled_ellipse(x1,y1,a,b,cl);
963  return 1;
964}
965
966static int luaCB_draw_string( lua_State* L ) {
967  coord x1=luaL_checknumber(L,1);
968  coord y1=luaL_checknumber(L,2);
969  const char *t = luaL_checkstring( L, 3 );
970  color clf=get_color(luaL_checknumber(L,4));
971  color clb=get_color(luaL_checknumber(L,5));
972  clf=256*clb+clf;
973  draw_string(x1,y1,t,clf);
974  return 1;
975}
976
977static int luaCB_draw_clear( lua_State* L ) {
978  draw_restore();
979  return 1;
980}
981
982static int luaCB_autostarted( lua_State* L )
983{
984  lua_pushboolean( L, camera_get_script_autostart() );
985  return 1;
986}
987
988static int luaCB_get_autostart( lua_State* L )
989{
990  lua_pushnumber( L, conf.script_startup );
991  return 1;
992}
993
994static int luaCB_set_autostart( lua_State* L )
995{
996  int to;
997  to = luaL_checknumber( L, 1 );
998  if ( to >= 0 && to <= 2 ) conf.script_startup = to;
999  conf_save();
1000  return 0;
1001}
1002
1003static int luaCB_get_usb_power( lua_State* L )
1004{
1005  if (luaL_optnumber( L, 1, 0 )) lua_pushnumber( L, get_usb_power(1) );
1006  else lua_pushnumber( L, get_usb_power(0) );
1007  return 1;
1008}
1009
1010static int luaCB_exit_alt( lua_State* L )
1011{
1012  exit_alt();
1013  return 0;
1014}
1015
1016// optional parameter is 0 for soft shutdown (default) or 1 for hard/immediate
1017static int luaCB_shut_down( lua_State* L )
1018{
1019  if ( luaL_optnumber(L,1,0) == 1 )
1020  {
1021    shutdown();
1022  } else {
1023  camera_shutdown_in_a_second();
1024  }
1025  return 0;
1026}
1027
1028static int luaCB_print_screen( lua_State* L )
1029{
1030 
1031  if (lua_isboolean( L, 1 ))
1032    script_print_screen_statement( lua_toboolean( L, 1 ) );
1033  else
1034    script_print_screen_statement( luaL_checknumber( L, 1 )+10000 );
1035  return 0;
1036}
1037
1038static int luaCB_get_movie_status( lua_State* L )
1039{
1040  lua_pushnumber( L, movie_status );
1041  return 1;
1042}
1043
1044static int luaCB_set_movie_status( lua_State* L )
1045{
1046  int to;
1047  switch(luaL_checknumber( L, 1 )) {
1048    case 1:
1049      if (movie_status == 4) {
1050        movie_status = 1;
1051      }
1052    break;
1053    case 2:
1054      if (movie_status == 1) {
1055        movie_status = 4;
1056      }
1057    break;
1058    case 3:
1059      if (movie_status == 1 || movie_status == 4) {
1060        movie_status = 5;
1061      }
1062    break;
1063  }
1064  return 0;
1065}
1066
1067static int luaCB_get_drive_mode( lua_State* L )
1068{
1069  lua_pushnumber( L, shooting_get_drive_mode() );
1070  return 1;
1071}
1072
1073static int luaCB_get_focus_mode( lua_State* L )
1074{
1075  lua_pushnumber( L, shooting_get_prop(PROPCASE_FOCUS_MODE) );
1076  return 1;
1077}
1078
1079static int luaCB_get_flash_mode( lua_State* L )
1080{
1081  lua_pushnumber( L, shooting_get_prop(PROPCASE_FLASH_MODE) );
1082  return 1;
1083}
1084
1085static int luaCB_get_shooting( lua_State* L )
1086{
1087  lua_pushboolean( L, shooting_get_prop(PROPCASE_SHOOTING) );
1088  return 1;
1089}
1090
1091static int luaCB_get_flash_ready( lua_State* L )
1092{
1093  lua_pushboolean( L, shooting_get_prop(PROPCASE_IS_FLASH_READY) );
1094  return 1;
1095}
1096
1097static int luaCB_get_IS_mode( lua_State* L )
1098{
1099  lua_pushnumber( L, shooting_get_prop(PROPCASE_IS_MODE) );
1100  return 1;
1101}
1102
1103static int luaCB_get_orientation_sensor( lua_State* L )
1104{
1105  lua_pushnumber( L, shooting_get_prop(PROPCASE_ORIENTATION_SENSOR) );
1106  return 1;
1107}
1108
1109static int luaCB_get_zoom_steps( lua_State* L )
1110{
1111  lua_pushnumber( L, zoom_points );
1112  return 1;
1113}
1114
1115static int luaCB_get_nd_present( lua_State* L )
1116{
1117  int to;
1118  #if !CAM_HAS_ND_FILTER
1119  to = 0;
1120  #endif
1121  #if CAM_HAS_ND_FILTER && !CAM_HAS_IRIS_DIAPHRAGM
1122  to = 1;
1123  #endif
1124  #if CAM_HAS_ND_FILTER && CAM_HAS_IRIS_DIAPHRAGM
1125  to = 2;
1126  #endif
1127  lua_pushnumber( L, to );
1128  return 1;
1129}
1130
1131static int luaCB_get_propset( lua_State* L )
1132{
1133  lua_pushnumber( L, CAM_PROPSET );
1134  return 1;
1135}
1136
1137static int luaCB_get_ev( lua_State* L )
1138{
1139  lua_pushnumber( L, shooting_get_prop(PROPCASE_EV_CORRECTION_1) );
1140  return 1;
1141}
1142
1143static int luaCB_set_ev( lua_State* L )
1144{
1145  int to;
1146  to = luaL_checknumber( L, 1 );
1147  shooting_set_prop(PROPCASE_EV_CORRECTION_1, to);
1148  shooting_set_prop(PROPCASE_EV_CORRECTION_2, to);
1149  return 0;
1150}
1151
1152static int luaCB_get_histo_range( lua_State* L )
1153{
1154  int from = (luaL_checknumber(L,1));
1155  int to = (luaL_checknumber(L,2));
1156  if (shot_histogram_isenabled()) lua_pushnumber( L, shot_histogram_get_range(from, to) );
1157  else lua_pushnumber( L, -1 ); // TODO should probably return nil
1158  return 1;
1159}
1160
1161static int luaCB_shot_histo_enable( lua_State* L )
1162{
1163  shot_histogram_set(luaL_checknumber( L, 1 ));
1164  return 0;
1165}
1166
1167static int luaCB_play_sound( lua_State* L )
1168{
1169  play_sound(luaL_checknumber( L, 1 ));
1170  return 0;
1171}
1172
1173static int luaCB_get_temperature( lua_State* L )
1174{
1175  int which = (luaL_checknumber( L, 1 ));
1176  int temp = -100; // do something insane if users passes bad value
1177  switch (which)
1178  {
1179    case 0:
1180      temp = get_optical_temp();
1181      break;
1182    case 1:
1183      temp = get_ccd_temp();
1184      break;
1185    case 2:
1186      temp = get_battery_temp();
1187      break;
1188  }
1189  lua_pushnumber( L, temp );
1190  return 1;
1191}
1192
1193static int luaCB_get_time( lua_State* L )
1194{
1195  int r = -1;
1196  unsigned long t2 = time(NULL);
1197  static struct tm *ttm;
1198  ttm = localtime(&t2);
1199  const char *t = luaL_checkstring( L, 1 );
1200  if (strncmp("s", t, 1)==0) r = ( L, ttm->tm_sec );
1201  else if (strncmp("m", t, 1)==0) r = ( L, ttm->tm_min );
1202  else if (strncmp("h", t, 1)==0) r = ( L, ttm->tm_hour );
1203  else if (strncmp("D", t, 1)==0) r = ( L, ttm->tm_mday );
1204  else if (strncmp("M", t, 1)==0) r = ( L, ttm->tm_mon+1 );
1205  else if (strncmp("Y", t, 1)==0) r = ( L, 1900+ttm->tm_year );
1206  lua_pushnumber( L, r );
1207  return 1;
1208}
1209
1210/*
1211  val=peek(address[,size])
1212  return the value found at address in memory, or nil if address or size is invalid
1213  size is optional 1=byte 2=halfword 4=word. defaults is 4
1214*/
1215static int luaCB_peek( lua_State* L )
1216{
1217  unsigned addr = luaL_checknumber(L,1);
1218  unsigned size = luaL_optnumber(L, 2, 4);
1219  switch(size) {
1220    case 1:
1221      lua_pushnumber( L, *(unsigned char *)(addr) );
1222    break;
1223    case 2:
1224      if (addr & 0x1) {
1225        lua_pushnil(L);
1226      }
1227      else {
1228        lua_pushnumber( L, *(unsigned short *)(addr) );
1229      }
1230    break;
1231    case 4:
1232      if (addr & 0x3) {
1233        lua_pushnil(L);
1234      }
1235      else {
1236        lua_pushnumber( L, *(unsigned *)(addr) );
1237      }
1238    break;
1239    default:
1240      lua_pushnil(L);
1241
1242  }
1243  return 1;
1244}
1245
1246/*
1247  status=poke(address,value[,size])
1248  writes value to address in memory
1249  size is optional 1=byte 2=halfword 4=word. defaults is 4
1250  returns true, or nil if address or size is invalid
1251*/
1252static int luaCB_poke( lua_State* L )
1253{
1254  unsigned addr = luaL_checknumber(L,1);
1255  unsigned val = luaL_checknumber(L,2);
1256  unsigned size = luaL_optnumber(L, 3, 4);
1257  int status = 0;
1258  switch(size) {
1259    case 1:
1260        *(unsigned char *)(addr) = (unsigned char)val;
1261        status=1;
1262    break;
1263    case 2:
1264      if (!(addr & 0x1)) {
1265        *(unsigned short *)(addr) = (unsigned short)val;
1266        status=1;
1267      }
1268    break;
1269    case 4:
1270      if (!(addr & 0x3)) {
1271        *(unsigned *)(addr) = val;
1272        status=1;
1273      }
1274    break;
1275  }
1276  if(status) {
1277    lua_pushboolean(L,1);
1278  }
1279  else {
1280    lua_pushnil(L);
1281  }
1282  return 1;
1283}
1284
1285static int luaCB_bitand( lua_State* L )
1286{
1287  int v1 = (luaL_checknumber(L,1));
1288  int v2 = (luaL_checknumber(L,2));
1289  lua_pushnumber( L, v1 & v2 );
1290  return 1;
1291}
1292
1293static int luaCB_bitor( lua_State* L )
1294{
1295  int v1 = (luaL_checknumber(L,1));
1296  int v2 = (luaL_checknumber(L,2));
1297  lua_pushnumber( L, v1 | v2 );
1298  return 1;
1299}
1300
1301static int luaCB_bitxor( lua_State* L )
1302{
1303  int v1 = (luaL_checknumber(L,1));
1304  int v2 = (luaL_checknumber(L,2));
1305  lua_pushnumber( L, v1 ^ v2 );
1306  return 1;
1307}
1308
1309static int luaCB_bitshl( lua_State* L )
1310{
1311  int val = (luaL_checknumber(L,1));
1312  unsigned shift = (luaL_checknumber(L,2));
1313  lua_pushnumber( L, val << shift );
1314  return 1;
1315}
1316
1317static int luaCB_bitshri( lua_State* L )
1318{
1319  int val = (luaL_checknumber(L,1));
1320  unsigned shift = (luaL_checknumber(L,2));
1321  lua_pushnumber( L, val >> shift );
1322  return 1;
1323}
1324
1325static int luaCB_bitshru( lua_State* L )
1326{
1327  unsigned val = (luaL_checknumber(L,1));
1328  unsigned shift = (luaL_checknumber(L,2));
1329  lua_pushnumber( L, val >> shift );
1330  return 1;
1331}
1332
1333static int luaCB_bitnot( lua_State* L )
1334{
1335  unsigned val = (luaL_checknumber(L,1));
1336  lua_pushnumber( L, ~val );
1337  return 1;
1338}
1339
1340static void set_string_field(lua_State* L, const char *key, const char *val)
1341{
1342  lua_pushstring(L, val);
1343  lua_setfield(L, -2, key);
1344}
1345
1346static void set_number_field(lua_State* L, const char *key, int val)
1347{
1348  lua_pushnumber(L, val);
1349  lua_setfield(L, -2, key);
1350}
1351
1352static int luaCB_get_buildinfo( lua_State* L )
1353{
1354  lua_createtable(L, 0, 8);
1355  set_string_field( L,"platform", PLATFORM );
1356  set_string_field( L,"platsub", PLATFORMSUB );
1357  set_string_field( L,"version", HDK_VERSION );
1358  set_string_field( L,"build_number", BUILD_NUMBER );
1359  set_string_field( L,"build_date", __DATE__ );
1360  set_string_field( L,"build_time", __TIME__ );
1361#ifndef CAM_DRYOS
1362  set_string_field( L,"os", "vxworks" );
1363#else
1364  set_string_field( L,"os", "dryos" );
1365#endif
1366  set_number_field( L, "platformid", PLATFORMID );
1367  return 1;
1368}
1369
1370static int luaCB_get_mode( lua_State* L )
1371{
1372  int m = mode_get();
1373  lua_pushboolean( L, (m&MODE_MASK) != MODE_PLAY );
1374  lua_pushboolean( L, MODE_IS_VIDEO(m) );
1375  lua_pushnumber( L, m );
1376  return 3;
1377}
1378
1379// TODO sanity check file ?
1380static int luaCB_set_raw_develop( lua_State* L )
1381{
1382  raw_prepare_develop(luaL_optstring( L, 1, NULL ));
1383  return 0;
1384}
1385
1386static int luaCB_raw_merge_start( lua_State* L )
1387{
1388  int op = luaL_checknumber(L,1);
1389  if (!module_rawop_load())
1390    return luaL_argerror(L,1,"fail to load raw merge module");
1391  if (op == RAW_OPERATION_SUM || op == RAW_OPERATION_AVERAGE) {
1392    librawop.raw_merge_start(op);
1393  }
1394  else {
1395    return luaL_argerror(L,1,"invalid raw merge op");
1396  }
1397  return 0;
1398}
1399
1400// TODO sanity check file ?
1401static int luaCB_raw_merge_add_file( lua_State* L )
1402{
1403  if (!module_rawop_load())
1404    return luaL_argerror(L,1,"fail to load raw merge module");
1405  librawop.raw_merge_add_file(luaL_checkstring( L, 1 ));
1406  return 0;
1407}
1408
1409static int luaCB_raw_merge_end( lua_State* L )
1410{
1411  if (!module_rawop_load())
1412    return luaL_argerror(L,1,"fail to load raw merge module");
1413  librawop.raw_merge_end();
1414  return 0;
1415}
1416
1417// Enable/disable LCD back light (input argument 1/0)
1418static int luaCB_set_backlight( lua_State* L )
1419{
1420  int val = (luaL_checknumber(L,1));
1421
1422  if (val > 0) TurnOnBackLight();
1423  else TurnOffBackLight();
1424  return 0;
1425}
1426
1427// get the string or number passed in index and return it as an event id
1428static unsigned levent_id_from_lua_arg( lua_State* L, int index)
1429{
1430  unsigned event_id;
1431  if (lua_type(L, index) == LUA_TSTRING) {
1432    const char *ev_name = lua_tostring(L, index);
1433        event_id = levent_id_for_name(ev_name);
1434    if (event_id == 0) {
1435        return luaL_error( L, "bad event name '%s'", ev_name );
1436    }
1437  }
1438  // could check here if it is in the table, but even valid ones can crash
1439  // so we avoid searching the table if given a number
1440  else if (lua_type(L,index) == LUA_TNUMBER){
1441        event_id = lua_tonumber(L,index);
1442  }
1443  else {
1444    return luaL_error( L, "expected event name or id" );
1445  }
1446  return event_id;
1447}
1448
1449/*
1450  get a value where boolean or 0/!0 are accepted for on/off.
1451  normal lua toboolean will convert 0 to true, but ubasic and c users
1452  will expect 0 to be off
1453  intentional HACK: numbers greater than 1 are returned as is
1454*/
1455static unsigned on_off_value_from_lua_arg( lua_State* L, int index)
1456{
1457  if( lua_isboolean(L,index) ) {
1458        return lua_toboolean(L,index);
1459  }
1460  else {
1461        return luaL_checknumber(L,index);
1462  }
1463}
1464
1465/*
1466  return the index of an event, given it's name or event id
1467*/
1468static unsigned levent_index_from_id_lua_arg( lua_State* L, int index )
1469{
1470  if (lua_type(L, index) == LUA_TSTRING) {
1471        return levent_index_for_name(lua_tostring(L, index));
1472  }
1473  else if (lua_type(L,index) == LUA_TNUMBER){
1474        return levent_index_for_id(lua_tonumber(L,index));
1475  }
1476  else {
1477    return luaL_error( L, "expected string or number" );
1478  }
1479}
1480
1481/*
1482  name,id,param = get_levent_def(event)
1483  event is an event id (number) or name (string)
1484  returns nil if event is not found
1485*/
1486static int luaCB_get_levent_def( lua_State* L )
1487{
1488  unsigned event_index = levent_index_from_id_lua_arg(L,1);
1489  if (event_index == LEVENT_INVALID_INDEX) {
1490    lua_pushnil(L);
1491    return 1;
1492  }
1493  lua_pushstring(L, levent_table[event_index].name);
1494  lua_pushnumber(L, levent_table[event_index].id);
1495  lua_pushnumber(L, levent_table[event_index].param);
1496  return 3;
1497}
1498
1499/*
1500  index=get_levent_index(event)
1501  event is an event id (number) or name (string)
1502  returns index or nil if not found
1503*/
1504static int luaCB_get_levent_index( lua_State* L )
1505{
1506  unsigned event_index = levent_index_from_id_lua_arg(L,1);
1507  if (event_index == LEVENT_INVALID_INDEX) {
1508    lua_pushnil(L);
1509  }
1510  else {
1511    lua_pushnumber(L, event_index);
1512  }
1513  return 1;
1514}
1515
1516/*
1517  name,id,param = get_levent_def_by_index(event_index)
1518  event_index is number index into the event table
1519  returns nil if event is not found
1520*/
1521static int luaCB_get_levent_def_by_index( lua_State* L )
1522{
1523  unsigned i = luaL_checknumber(L,1);
1524  if(i >= levent_count()) {
1525        lua_pushnil(L);
1526    return 1;
1527  }
1528  lua_pushstring(L, levent_table[i].name);
1529  lua_pushnumber(L, levent_table[i].id);
1530  lua_pushnumber(L, levent_table[i].param);
1531  return 3;
1532}
1533
1534/*
1535  post_levent_*(event[,unk])
1536  post the event with PostLogicalEventToUI or PostLogicaEventForNotPowerType
1537  This sends the event. The difference between functions isn't clear.
1538  event is an event id (number) or name (string).
1539  unk is an optional number whose meaning is unknown, defaults to zero.
1540    Based on code, other values would probably be a pointer.
1541        This is NOT the 3rd item in the event table.
1542*/
1543static int luaCB_post_levent_to_ui( lua_State* L )
1544{
1545  unsigned event_id,arg;
1546
1547  event_id = levent_id_from_lua_arg(L,1);
1548  arg = luaL_optnumber(L, 2, 0);
1549  PostLogicalEventToUI(event_id,arg);
1550  return 0;
1551}
1552
1553static int luaCB_post_levent_for_npt( lua_State* L )
1554{
1555  unsigned event_id,arg;
1556
1557  event_id = levent_id_from_lua_arg(L,1);
1558  arg = luaL_optnumber(L, 2, 0);
1559  PostLogicalEventForNotPowerType(event_id,arg);
1560  return 0;
1561}
1562
1563/*
1564  set_levent_active(event,state)
1565  event is an event id (number) or name (string)
1566  state is a numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
1567  exact meaning is unknown, but it has something to do with the delivery of the specified event.
1568*/
1569static int luaCB_set_levent_active( lua_State* L )
1570{
1571  unsigned event_id;
1572  unsigned state;
1573
1574  event_id = levent_id_from_lua_arg(L,1);
1575  state = on_off_value_from_lua_arg(L,2);
1576  SetLogicalEventActive(event_id,state);
1577  return 0;
1578}
1579
1580/*
1581  set_levent_script_mode(state)
1582  state is numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
1583  exact meaning is unknown, but it has something to do with the behavior of events and/or SetLogicalEventActive.
1584*/
1585static int luaCB_set_levent_script_mode( lua_State* L )
1586{
1587  SetScriptMode(on_off_value_from_lua_arg(L,1));
1588  return 0;
1589}
1590
1591/*
1592  result=set_capture_mode_canon(value)
1593  where value is a valid PROPCASE_SHOOTING_MODE value for the current camera
1594  result is true if the camera is in rec mode
1595*/
1596static int luaCB_set_capture_mode_canon( lua_State* L )
1597{
1598  int modenum = luaL_checknumber(L,1);
1599  // if the value as negative, assume it is a mistakenly sign extended PROPCASE_SHOOTING_MODE value
1600  if(modenum < 0)
1601    modenum &= 0xFFFF;
1602  lua_pushboolean( L, shooting_set_mode_canon(modenum) );
1603  return 1;
1604}
1605
1606/*
1607 result=set_capture_mode(modenum)
1608 where modenum is a valid CHDK modemap value
1609 result is true if modenum is a valid modemap value, otherwise false
1610*/
1611static int luaCB_set_capture_mode( lua_State* L )
1612{
1613  int modenum = luaL_checknumber(L,1);
1614  lua_pushboolean( L, shooting_set_mode_chdk(modenum) );
1615  return 1;
1616}
1617
1618/*
1619 result=is_capture_mode_valid(modenum)
1620 where modenum is a valid CHDK modemap value
1621 result is true if modenum is a valid modemap value, otherwise false
1622*/
1623static int luaCB_is_capture_mode_valid( lua_State* L )
1624{
1625  int modenum = luaL_checknumber(L,1);
1626  lua_pushboolean( L, shooting_mode_chdk2canon(modenum) != -1 );
1627  return 1;
1628}
1629
1630/*
1631  set_record(state)
1632  if state is 0 (or false) the camera is set to play mode. If 1 or true, the camera is set to record mode.
1633  NOTE: this only begins the mode change. Script should wait until get_mode() reflects the change,
1634  before doing anything that requires the new mode. e.g.
1635  set_record(true)
1636  while not get_mode() do
1637        sleep(10)
1638  end
1639*/
1640static int luaCB_set_record( lua_State* L )
1641{
1642  if(on_off_value_from_lua_arg(L,1)) {
1643    levent_set_record();
1644  }
1645  else {
1646    levent_set_play();
1647  }
1648  return 0;
1649}
1650
1651// switch mode (0 = playback, 1 = record)
1652// only for when USB is connected
1653static int luaCB_switch_mode_usb( lua_State* L )
1654{
1655  int mode = luaL_checknumber(L,1);
1656
1657  if ( mode != 0 && mode != 1 )
1658  {
1659    return 0;
1660  }
1661
1662  return switch_mode_usb(mode);
1663}
1664 
1665#ifdef CAM_CHDK_PTP
1666// PTP Live View functions
1667
1668// Function used to get viewport, bitmap and palette data via PTP
1669// Address of this function sent back to client program which then
1670// calls this with options to determine what to transfer
1671static int handle_video_transfer(ptp_data *data, int flags, int arg2)
1672{
1673    int total_size;             // Calculated total size of data to transfer to client
1674
1675    // Structure containing the info for the current live view frame
1676    // This information may change across calls
1677    struct {
1678        int vp_xoffset;             // Viewport X offset in pixels (for cameras with variable image size)
1679        int vp_yoffset;             // Viewpoer Y offset in pixels (for cameras with variable image size)
1680        int vp_width;               // Actual viewport width in pixels (for cameras with variable image size)
1681        int vp_height;              // Actual viewport height in pixels (for cameras with variable image size)
1682        int vp_buffer_start;        // Offset in data transferred where the viewport data starts
1683        int vp_buffer_size;         // Size of viewport data sent (in bytes)
1684        int bm_buffer_start;        // Offset in data transferred where the bitmap data starts
1685        int bm_buffer_size;         // Size of bitmap data sent (in bytes)
1686        int palette_type;           // Camera palette type
1687                                    // (0 = no palette, 1 = 16 x 4 byte AYUV values, 2 = 16 x 4 byte AYUV values with A = 0..3, 3 = 256 x 4 byte AYUV values with A = 0..3)
1688        int palette_buffer_start;   // Offset in data transferred where the palette data starts
1689        int palette_buffer_size;    // Size of palette data sent (in bytes)
1690    } vid_info;
1691
1692    // Populate the above structure with the current default details
1693    vid_info.vp_xoffset = vid_get_viewport_xoffset_proper();
1694    vid_info.vp_yoffset = vid_get_viewport_yoffset_proper();
1695    vid_info.vp_width = vid_get_viewport_width_proper();
1696    vid_info.vp_height = vid_get_viewport_height_proper();
1697    vid_info.vp_buffer_start = 0;
1698    vid_info.vp_buffer_size = 0;
1699    vid_info.bm_buffer_start = 0;
1700    vid_info.bm_buffer_size = 0;
1701    vid_info.palette_type = vid_get_palette_type();
1702    vid_info.palette_buffer_start = 0;
1703    vid_info.palette_buffer_size = 0;
1704
1705    total_size = sizeof(vid_info);
1706
1707    // Add viewport details if requested
1708    if ( flags & 0x1 ) // live buffer
1709    {
1710        vid_info.vp_buffer_start = total_size;
1711        vid_info.vp_buffer_size = (vid_get_viewport_buffer_width_proper()*vid_get_viewport_max_height()*6)/4;
1712        total_size += vid_info.vp_buffer_size;
1713    }
1714
1715    // Add bitmap details if requested
1716    if ( flags & 0x4 ) // bitmap buffer
1717    {
1718        vid_info.bm_buffer_start = total_size;
1719        vid_info.bm_buffer_size = vid_get_bitmap_buffer_width()*vid_get_bitmap_screen_height();
1720        total_size += vid_info.bm_buffer_size;
1721    }
1722
1723    // Add palette detals if requested
1724    if ( flags & 0x8 ) // bitmap palette
1725    {
1726        vid_info.palette_buffer_start = total_size;
1727        vid_info.palette_buffer_size = vid_get_palette_size();
1728        total_size += vid_info.palette_buffer_size;
1729    }
1730
1731    // Send header structure (along with total size to be sent)
1732    data->send_data(data->handle,(char*)&vid_info,sizeof(vid_info),total_size,0,0,0);
1733
1734    // Send viewport data if requested
1735    if ( flags & 0x1 )
1736    {
1737        data->send_data(data->handle,vid_get_viewport_active_buffer(),vid_info.vp_buffer_size,0,0,0,0);
1738    }
1739
1740    // Send bitmap data if requested
1741    if ( flags & 0x4 )
1742    {
1743        data->send_data(data->handle,vid_get_bitmap_active_buffer(),vid_info.bm_buffer_size,0,0,0,0);
1744    }
1745
1746    // Send palette data if requested
1747    if ( flags & 0x8 )
1748    {
1749        data->send_data(data->handle,vid_get_bitmap_active_palette(),vid_info.palette_buffer_size,0,0,0,0);
1750    }
1751
1752    return 0;
1753}
1754
1755// Lua function to return base info for PTP live view, including address of above transfer function
1756static int luaCB_get_video_details( lua_State* L )
1757{
1758    // Structure to popualate with live view details
1759    // These details are static and only need to be retrieved once
1760    struct {
1761        int transfer_function;      // Address of transfer function above
1762        int vp_max_width;           // Maximum viewport width (in pixels)
1763        int vp_max_height;          // Maximum viewport height (in pixels)
1764        int vp_buffer_width;        // Viewport buffer width in case buffer is wider than visible viewport (in pixels)
1765        int bm_max_width;           // Maximum width of bitmap (in pixels)
1766        int bm_max_height;          // Maximum height of bitmap (in pixels)
1767        int bm_buffer_width;        // Bitmap buffer width in case buffer is wider than visible bitmap (in pixels)
1768        int lcd_aspect_ratio;       // 0 = 4:3, 1 = 16:9
1769    } details;
1770
1771    // Populate structure info
1772    details.transfer_function = (int) handle_video_transfer;
1773    details.vp_max_width = vid_get_viewport_max_width();
1774    details.vp_max_height = vid_get_viewport_max_height();
1775    details.vp_buffer_width = vid_get_viewport_buffer_width_proper();
1776#if CAM_USES_ASPECT_CORRECTION
1777    details.bm_max_width = ASPECT_XCORRECTION(vid_get_bitmap_screen_width());
1778#else
1779    details.bm_max_width = vid_get_bitmap_screen_width();
1780#endif
1781    details.bm_max_height = vid_get_bitmap_screen_height();
1782    details.bm_buffer_width = vid_get_bitmap_buffer_width();
1783    details.lcd_aspect_ratio = vid_get_aspect_ratio();
1784
1785    // Send data back to client
1786    lua_pushlstring( L, (char *) &details, sizeof(details) );
1787
1788    return 1;
1789}
1790#endif
1791
1792/*
1793pack the lua args into a buffer to pass to the native code calling functions
1794currently only handles strings/numbers
1795start is the stack index of the first arg
1796*/
1797#ifdef OPT_LUA_CALL_NATIVE
1798static int pack_native_args( lua_State* L, unsigned start, unsigned *argbuf)
1799{
1800  unsigned i;
1801  unsigned end = lua_gettop(L);
1802
1803  for(i = start; i <= end; i++,argbuf++) {
1804    if (lua_type(L, i) == LUA_TSTRING) {
1805        *argbuf=(unsigned)lua_tostring( L, i);
1806    }
1807    else if (lua_type(L, i) == LUA_TNUMBER) {
1808        *argbuf=lua_tonumber( L, i);
1809    }
1810    else {
1811      return 0;
1812    }
1813  }
1814  return 1;
1815}
1816
1817/*
1818Native function call interface. Can be used to call canon eventprocs or arbitrary
1819pointers.
1820
1821NOTE: this is preliminary, interface may change in later versions!
1822All arguments must be strings or numbers.
1823If the function expects to modify it's arguments via a pointer,
1824then you must provide a number that is a valid pointer.
1825
1826You can use the "AllocateMemory" eventproc to obtain buffers.
1827
1828If the function tries to write to a string passed from lua, Bad Things may happen.
1829
1830This is potentially dangerous, functions exist which can destroy the onboard firmware.
1831*/
1832
1833/*
1834result=call_func_ptr(ptr,...)
1835ptr: address of a valid ARM or Thumb function, which uses the normal C calling convention.
1836result: R0 value after the call returns
1837*/
1838static int luaCB_call_func_ptr( lua_State* L)
1839{
1840  unsigned *argbuf=NULL;
1841  unsigned i;
1842  unsigned n_args = lua_gettop(L)-1;
1843  void *fptr;
1844
1845  fptr=(void *)luaL_checknumber( L, 1 );
1846
1847  if (n_args) {
1848    argbuf=malloc(n_args * 4);
1849    if(!argbuf) {
1850      return luaL_error( L, "malloc fail" );
1851    }
1852    if(!pack_native_args(L, 2, argbuf)) {
1853      free(argbuf);
1854      return luaL_error( L, "expected string or number" );
1855    }
1856  }
1857 
1858  lua_pushnumber( L, call_func_ptr(fptr, argbuf, n_args) );
1859  free(argbuf);
1860  return 1;
1861}
1862
1863/*
1864Call an event procedure
1865
1866result=call_event_proc("EventprocName",...)
1867result is the value returned by ExecuteEventProcedure, which is -1 if the eventproc is not found,
1868or the eventproc return value (which could also be -1)
1869NOTE:
1870Many eventprocs are not registered by default, but can be loaded by calling another event proc
1871Some useful ones are
1872SystemEventInit
1873        includes AllocateMemory, FreeMemory, sprintf, memcpy, Fut functions, log ...
1874UI_RegistDebugEventProc
1875        includes capture mode functions, PTM_ functions and much more
1876RegisterProductTestEvent
1877        includes PT_ functions
1878
1879Others:
1880RegisterShootSeqEvent
1881RegisterNRTableEvent
1882*/
1883
1884// grab from lowlevel
1885extern unsigned _ExecuteEventProcedure(const char *name,...);
1886static int luaCB_call_event_proc( lua_State* L )
1887{
1888  const char *evpname;
1889  unsigned *argbuf;
1890  unsigned i;
1891  unsigned n_args = lua_gettop(L);
1892
1893  evpname=luaL_checkstring( L, 1 );
1894
1895  argbuf=malloc(n_args * 4);
1896  if (!argbuf) {
1897    return luaL_error( L, "malloc fail" );
1898  }
1899
1900  // event proc name is first arg
1901  *argbuf = (unsigned)evpname;
1902 
1903  if(!pack_native_args(L,2,argbuf+1)) {
1904    free(argbuf);
1905    return luaL_error( L, "expected string or number" );
1906  }
1907 
1908  lua_pushnumber( L, call_func_ptr(_ExecuteEventProcedure,argbuf,n_args) );
1909  free(argbuf);
1910  return 1;
1911}
1912
1913#endif // OPT_LUA_CALL_NATIVE
1914
1915/*
1916result = reboot(["filename"])
1917returns false on failure, does not return on success
1918see lib/armutil/reboot.c for details
1919*/
1920static int luaCB_reboot( lua_State* L )
1921{
1922        lua_pushboolean(L, reboot(luaL_optstring( L, 1, NULL )));
1923        return 1;
1924}
1925
1926static int luaCB_get_config_value( lua_State* L ) {
1927    unsigned int argc = lua_gettop(L);
1928    unsigned int id, i;
1929    int ret = 1;
1930    tConfigVal configVal;
1931   
1932    if( argc>=1 ) {
1933        id = luaL_checknumber(L, 1);
1934        switch( conf_getValue(id, &configVal) ) {
1935            case CONF_VALUE:
1936                lua_pushnumber(L, configVal.numb);
1937            break;
1938            case CONF_INT_PTR:
1939                lua_createtable(L, 0, configVal.numb);
1940                for( i=0; i<configVal.numb; i++ ) {
1941                    lua_pushinteger(L, configVal.pInt[i]);
1942                    lua_rawseti(L, -2, i+1);  //t[i+1]=configVal.pInt[i]
1943                }
1944            break;
1945            case CONF_CHAR_PTR:
1946                lua_pushstring(L, configVal.str);
1947            break;
1948            case CONF_OSD_POS_PTR:
1949                lua_pushnumber(L, configVal.pos.x);
1950                lua_pushnumber(L, configVal.pos.y); ret++;
1951            break;
1952            default:
1953                if( argc>=2) { //Default
1954                    ret = argc-1;
1955                } else {
1956                    lua_pushnil(L);
1957                }
1958            break;
1959        }
1960    } else {
1961        lua_pushnil(L);
1962    }
1963    return ret;
1964}
1965
1966static int luaCB_set_config_value( lua_State* L ) {
1967    unsigned int argc = lua_gettop(L);
1968    unsigned int id, i, j;
1969    tConfigVal configVal = {0,0,0,0};  //initialize isXXX
1970   
1971    if( argc>=2 ) {
1972        id = luaL_checknumber(L, 1);
1973        for( i=2; i<=argc; i++) {
1974            switch( lua_type(L, i) ) {
1975                case LUA_TNUMBER:
1976                    if( !configVal.isNumb ) {
1977                        configVal.numb = luaL_checknumber(L, i);
1978                        configVal.isNumb++;
1979                    }
1980                    switch( configVal.isPos ) {
1981                        case 0: configVal.pos.x = luaL_checknumber(L, i); configVal.isPos++; break;
1982                        case 1: configVal.pos.y = luaL_checknumber(L, i); configVal.isPos++; break;
1983                    }
1984                break;
1985                case LUA_TSTRING:
1986                    if( !configVal.isStr ) {
1987                        configVal.str = (char*)luaL_checkstring(L, i);
1988                        configVal.isStr++;
1989                    }
1990                break;
1991                case LUA_TTABLE:
1992                    if( !configVal.isPInt ) {
1993                        configVal.numb = lua_objlen(L, i);
1994                        if( configVal.pInt ) {
1995                            free(configVal.pInt);
1996                            configVal.pInt = NULL;
1997                        }
1998                        configVal.pInt = malloc(configVal.numb*sizeof(int));
1999                        if( configVal.pInt ) {
2000                            for( j=1; j<=configVal.numb; j++) {
2001                                lua_rawgeti(L, i, j);
2002                                configVal.pInt[j-1] = lua_tointeger(L, -1);
2003                                lua_pop(L, 1);
2004                            }
2005                        }
2006                        configVal.isPInt++;
2007                    }
2008                break;
2009            }
2010        }
2011        lua_pushboolean(L, conf_setValue(id, configVal));
2012        if( configVal.pInt ) {
2013            free(configVal.pInt);
2014            configVal.pInt = NULL;
2015        }
2016    } else lua_pushboolean(L, 0);
2017    return 1;
2018}
2019#ifdef CAM_CHDK_PTP
2020/*
2021msg = read_usb_msg([timeout])
2022read a message from the CHDK ptp interface.
2023Returns the next available message as a string, or nil if no messages are available
2024If timeout is given and not zero, wait until a message is available or timeout expires
2025*/
2026static int luaCB_read_usb_msg( lua_State* L )
2027{
2028  int timeout = luaL_optnumber( L, 1, 0 );
2029  if(timeout) {
2030    action_push(timeout);
2031    action_push(AS_SCRIPT_READ_USB_MSG);
2032    return lua_yield( L, 0 );
2033  }
2034  ptp_script_msg *msg = ptp_script_read_msg();
2035  if(msg) {
2036    lua_pushlstring(L,msg->data,msg->size);
2037    return 1;
2038  }
2039  lua_pushnil(L);
2040  return 1;
2041}
2042
2043/*
2044status = write_usb_msg(msg,[timeout])
2045writes a message to the CHDK ptp interface
2046msg may be nil, boolean, number, string or table (table has some restrictions, will be converted to string)
2047returns true if the message was queued successfully, otherwise false
2048if timeout is set and not zero, wait until message is written or timeout expires
2049NOTE strings will not include a terminating NULL, must be handled by recipient
2050*/
2051static int luaCB_write_usb_msg( lua_State* L )
2052{
2053  ptp_script_msg *msg;
2054  int timeout = luaL_optnumber( L, 2, 0 );
2055  // TODO would it be better to either ignore this or return nil ?
2056  // a write_usb_msg(function_which_returns_no_value()) is an error in this case
2057  // replacing with nil might be more luaish
2058  if(lua_gettop(L) < 1) {
2059    return luaL_error(L,"missing argument");
2060  }
2061  msg=lua_create_usb_msg(L,1,PTP_CHDK_S_MSGTYPE_USER);
2062  // for user messages, trying to create a message from an incompatible type throws an error
2063  if(msg->subtype == PTP_CHDK_TYPE_UNSUPPORTED) {
2064    free(msg);
2065    return luaL_error(L,"unsupported type");
2066  }
2067  if(!msg) {
2068    return luaL_error(L,"failed to create message");
2069  }
2070  if(timeout) {
2071    action_push(timeout);
2072    action_push((int)msg);
2073    action_push(AS_SCRIPT_WRITE_USB_MSG);
2074    return lua_yield( L, 0 );
2075  }
2076  lua_pushboolean(L,ptp_script_write_msg(msg));
2077  return 1;
2078}
2079#endif
2080
2081/* helper for meminfo to set table field only if valid */
2082static void set_meminfo_num( lua_State* L,const char *name, int val) {
2083    if(val != -1) {
2084        set_number_field( L, name, val );
2085    }
2086}
2087/*
2088meminfo=get_meminfo([heapname])
2089get camera memory information
2090heapname="system" or "exmem" if not given, meminfo is returned for heap used by CHDK for malloc
2091meminfo is false if the requested heapname isn't valid ("exmem" when exmem is not enabled, or unknown)
2092otherwise, a table of the form
2093meminfo = {
2094    name -- string "system" or "exmem"
2095    chdk_malloc -- bool, this is the heap used by CHDK for malloc
2096    chdk_start -- number, load address of CHDK
2097    chdk_size -- number, size of CHDK image
2098    -- all the following are numbers, will not be set if not available
2099    start_address
2100    end_address
2101    total_size
2102    allocated_size
2103    allocated_peak
2104    allocated_count
2105    free_size
2106    free_block_max_size
2107    free_block_count
2108}
2109NOTES
2110* under vxworks and cameras without GetMemInfo only the only valid fields
2111  for the system heap will be those defined by chdk and free_block_max_size
2112* the meaning of fields may not correspond exactly between exmem and system
2113*/
2114static int luaCB_get_meminfo( lua_State* L ) {
2115    // for memory info, duplicated from lowlevel
2116    extern const char _start,_end;
2117
2118#if defined(OPT_EXMEM_MALLOC) && !defined(OPT_EXMEM_TESTING)
2119    const char *default_heapname="exmem";
2120#else
2121    const char *default_heapname="system";
2122#endif
2123    const char *heapname = luaL_optstring( L, 1, default_heapname );
2124    cam_meminfo meminfo;
2125
2126    if(strcmp(heapname,"system") == 0) {
2127#if defined(CAM_FIRMWARE_MEMINFO)
2128        GetMemInfo(&meminfo);
2129#else
2130        memset(&meminfo,0xFF,sizeof(cam_meminfo));
2131        meminfo.free_block_max_size = core_get_free_memory();
2132#endif
2133    }
2134#if defined(OPT_EXMEM_MALLOC) && !defined(OPT_EXMEM_TESTING)
2135    else if(strcmp(heapname,"exmem") == 0) {
2136        GetExMemInfo(&meminfo);
2137        meminfo.allocated_count = -1; // not implemented in suba
2138    }
2139#endif
2140    else {
2141        lua_pushboolean(L,0);
2142        return 1;
2143    }
2144    // adjust start and size, if CHDK is loaded at heap start
2145    if(meminfo.start_address == (int)(&_start)) {
2146        meminfo.start_address += MEMISOSIZE;
2147        meminfo.total_size -= MEMISOSIZE;
2148    }
2149    lua_createtable(L, 0, 13); // might not always use 13, but doesn't hurt
2150    set_string_field( L,"name", heapname );
2151    lua_pushboolean( L, (strcmp(heapname,default_heapname)==0));
2152    lua_setfield(L, -2, "chdk_malloc");
2153    set_number_field( L, "chdk_start", (int)(&_start) );
2154    set_number_field( L, "chdk_size", MEMISOSIZE );
2155    set_meminfo_num( L, "start_address", meminfo.start_address );
2156    set_meminfo_num( L, "end_address", meminfo.end_address);
2157    set_meminfo_num( L, "total_size", meminfo.total_size);
2158    set_meminfo_num( L, "allocated_size", meminfo.allocated_size);
2159    set_meminfo_num( L, "allocated_peak", meminfo.allocated_peak);
2160    set_meminfo_num( L, "allocated_count", meminfo.allocated_count);
2161    set_meminfo_num( L, "free_size", meminfo.free_size);
2162    set_meminfo_num( L, "free_block_max_size", meminfo.free_block_max_size);
2163    set_meminfo_num( L, "free_block_count", meminfo.free_block_count);
2164    return 1;
2165}
2166
2167/*
2168set scheduling parameters
2169old_max_count,old_max_ms=set_yield(max_count,max_ms)
2170*/
2171static int luaCB_set_yield( lua_State* L )
2172{
2173  lua_pushnumber(L,yield_max_count);
2174  lua_pushnumber(L,yield_max_ms);
2175  yield_max_count = luaL_optnumber(L,1,YIELD_MAX_COUNT_DEFAULT);
2176  yield_max_ms = luaL_optnumber(L,2,YIELD_MAX_MS_DEFAULT);
2177  return 2;
2178}
2179
2180
2181static void register_func( lua_State* L, const char *name, void *func) {
2182  lua_pushcfunction( L, func );
2183  lua_setglobal( L, name );
2184}
2185
2186#define FUNC( X ) { #X, luaCB_##X },
2187static const luaL_Reg chdk_funcs[] = {
2188  FUNC(shoot)
2189  FUNC(sleep)
2190  FUNC(cls)
2191  FUNC(set_console_layout)
2192  FUNC(set_console_autoredraw)
2193  FUNC(console_redraw)
2194  FUNC(get_av96)
2195  FUNC(get_av96)
2196  FUNC(get_bv96)
2197  FUNC(get_day_seconds)
2198  FUNC(get_disk_size)
2199  FUNC(get_dof)
2200  FUNC(get_far_limit)
2201  FUNC(get_free_disk_space)
2202  FUNC(get_focus)
2203  FUNC(get_hyp_dist)
2204  FUNC(get_iso_market)
2205  FUNC(get_iso_mode)
2206  FUNC(get_iso_real)
2207  FUNC(get_jpg_count)
2208  FUNC(get_near_limit)
2209  FUNC(get_prop)
2210  FUNC(get_prop_str)
2211  FUNC(get_raw_count)
2212  FUNC(get_raw_nr)
2213  FUNC(get_raw)
2214  FUNC(get_sv96)
2215  FUNC(get_tick_count)
2216  FUNC(get_tv96)
2217  FUNC(get_user_av_id)
2218  FUNC(get_user_av96)
2219  FUNC(get_user_tv_id)
2220  FUNC(get_user_tv96)
2221  FUNC(get_vbatt)
2222  FUNC(get_zoom)
2223  FUNC(get_exp_count)
2224  FUNC(get_flash_params_count)
2225  FUNC(get_parameter_data)
2226
2227  FUNC(set_av96_direct)
2228  FUNC(set_av96)
2229  FUNC(set_focus)
2230  FUNC(set_iso_mode)
2231  FUNC(set_iso_real)
2232  FUNC(set_led)
2233  FUNC(set_nd_filter)
2234  FUNC(set_prop)
2235  FUNC(set_prop_str)
2236  FUNC(set_raw_nr)
2237  FUNC(set_raw)
2238  FUNC(set_sv96)
2239  FUNC(set_tv96_direct)
2240  FUNC(set_tv96)
2241  FUNC(set_user_av_by_id_rel)
2242  FUNC(set_user_av_by_id)
2243  FUNC(set_user_av96)
2244  FUNC(set_user_tv_by_id_rel)
2245  FUNC(set_user_tv_by_id)
2246  FUNC(set_user_tv96)
2247  FUNC(set_zoom_speed)
2248  FUNC(set_zoom_rel)
2249  FUNC(set_zoom)
2250
2251  FUNC(wait_click)
2252  FUNC(is_pressed)
2253  FUNC(is_key)
2254#ifdef CAM_HAS_JOGDIAL
2255  FUNC(wheel_right)
2256  FUNC(wheel_left)
2257#endif
2258  FUNC(md_get_cell_diff)
2259  FUNC(md_detect_motion)
2260  FUNC(autostarted)
2261  FUNC(get_autostart)
2262  FUNC(set_autostart)
2263  FUNC(get_usb_power)
2264  FUNC(exit_alt)
2265  FUNC(shut_down)
2266  FUNC(print_screen)
2267
2268  FUNC(get_focus_mode)
2269  FUNC(get_propset)
2270  FUNC(get_zoom_steps)
2271  FUNC(get_drive_mode)
2272  FUNC(get_flash_mode)
2273  FUNC(get_shooting)
2274  FUNC(get_flash_ready)
2275  FUNC(get_IS_mode)
2276  FUNC(set_ev)
2277  FUNC(get_ev)
2278  FUNC(get_orientation_sensor)
2279  FUNC(get_nd_present)
2280  FUNC(get_movie_status)
2281  FUNC(set_movie_status)
2282 
2283  FUNC(get_histo_range)
2284  FUNC(shot_histo_enable)
2285  FUNC(play_sound)
2286  FUNC(get_temperature)
2287  FUNC(peek)
2288  FUNC(poke)
2289  FUNC(bitand)
2290  FUNC(bitor)
2291  FUNC(bitxor)
2292  FUNC(bitshl)
2293  FUNC(bitshri)
2294  FUNC(bitshru)
2295  FUNC(bitnot)
2296
2297  FUNC(get_time)
2298
2299  FUNC(get_buildinfo)
2300  FUNC(get_mode)
2301 
2302  FUNC(set_raw_develop)
2303  // NOTE these functions normally run in the spytask.
2304  // called from lua they will run from kbd task instead
2305  FUNC(raw_merge_start)
2306  FUNC(raw_merge_add_file)
2307  FUNC(raw_merge_end)
2308  FUNC(set_backlight)
2309   FUNC(set_aflock)
2310#ifdef OPT_CURVES
2311   FUNC(set_curve_state)
2312#endif
2313// get levent definition by name or id, nil if not found
2314   FUNC(get_levent_def)
2315// get levent definition by index, nil if out of range
2316   FUNC(get_levent_def_by_index)
2317// get levent index from name or ID
2318   FUNC(get_levent_index)
2319   FUNC(post_levent_to_ui)
2320   FUNC(post_levent_for_npt)
2321   FUNC(set_levent_active)
2322   FUNC(set_levent_script_mode)
2323
2324   FUNC(set_capture_mode)
2325   FUNC(set_capture_mode_canon)
2326   FUNC(is_capture_mode_valid)
2327
2328   FUNC(set_record)
2329   FUNC(switch_mode_usb)
2330#ifdef CAM_CHDK_PTP
2331   FUNC(get_video_details)
2332#endif
2333
2334#ifdef OPT_LUA_CALL_NATIVE
2335   FUNC(call_event_proc)
2336   FUNC(call_func_ptr)
2337#endif
2338   FUNC(reboot)
2339   FUNC(get_config_value)
2340   FUNC(set_config_value)
2341#ifdef CAM_CHDK_PTP
2342   FUNC(read_usb_msg)
2343   FUNC(write_usb_msg)
2344#endif
2345   FUNC(get_meminfo)
2346
2347   FUNC(file_browser)
2348   
2349   FUNC(draw_pixel)
2350   FUNC(draw_line)
2351   FUNC(draw_rect)
2352   FUNC(draw_rect_filled)
2353   FUNC(draw_ellipse)
2354   FUNC(draw_ellipse_filled)
2355   FUNC(draw_clear)
2356   FUNC(draw_string)
2357
2358   FUNC(set_yield)
2359
2360  {NULL, NULL},
2361};
2362
2363void register_lua_funcs( lua_State* L )
2364{
2365  const luaL_reg *r;
2366  lua_pushlightuserdata( L, action_push_click );
2367  lua_pushcclosure( L, luaCB_keyfunc, 1 );
2368  lua_setglobal( L, "click" );
2369
2370  lua_pushlightuserdata( L, action_push_press );
2371  lua_pushcclosure( L, luaCB_keyfunc, 1 );
2372  lua_setglobal( L, "press" );
2373
2374  lua_pushlightuserdata( L, action_push_release );
2375  lua_pushcclosure( L, luaCB_keyfunc, 1 );
2376  lua_setglobal( L, "release" );
2377
2378  for(r=chdk_funcs;r->name;r++) {
2379    lua_pushcfunction( L, r->func );
2380    lua_setglobal( L, r->name );
2381  }
2382#ifdef CAM_CHDK_PTP
2383   luaL_dostring(L,"function usb_msg_table_to_string(t)"
2384                    " local v2s=function(v)"
2385                        " local t=type(v)"
2386                        " if t=='string' then return v end"
2387                        " if t=='number' or t=='boolean' or t=='nil' then return tostring(v) end"
2388                        " return '' end"
2389                    " local r=''"
2390                    " for k,v in pairs(t) do"
2391                        " local s,vs=''"
2392                        " if type(v)=='table' then"
2393                            " for i=1,table.maxn(v) do"
2394                            " s=s..'\\t'..v2s(v[i]) end"
2395                        " else"
2396                            " vs=v2s(v)"
2397                            " if #vs then s=s..'\\t'..vs end"
2398                        " end"
2399                        " vs=v2s(k)"
2400                        " if #vs>0 and #s>0 then r=r..vs..s..'\\n' end"
2401                    " end"
2402                    " return r"
2403                   " end");
2404
2405#endif
2406}
Note: See TracBrowser for help on using the repository browser.