source: trunk/core/luascript.c @ 1452

Revision 1452, 58.7 KB checked in by philmoz, 18 months ago (diff)

Fix for Lua scripts that call the file browser. When script exits, pressing the Func/Set? key again re-entered the file browser instead of entering the script menu.

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