source: trunk/core/luascript.c @ 1829

Revision 1829, 67.4 KB checked in by msl, 14 months ago (diff)

Lua

+ Added missing command get_video_button(), previously only available for uBasic.

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