source: trunk/core/luascript.c @ 1828

Revision 1828, 67.3 KB checked in by philmoz, 14 months ago (diff)

Update to viewport functions and code using them to handle the G1X viewport system.
This is now more flexible by allowing viewport buffer offsets to be seperate from the viewport display offsets, it can handle stitch mode properly. This is also needed for reyalp's new live view system.

  • 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_drive_mode( lua_State* L )
1123{
1124  lua_pushnumber( L, shooting_get_drive_mode() );
1125  return 1;
1126}
1127
1128static int luaCB_get_focus_mode( lua_State* L )
1129{
1130  lua_pushnumber( L, shooting_get_real_focus_mode() );
1131  return 1;
1132}
1133
1134static int luaCB_get_focus_state( lua_State* L )
1135{
1136  lua_pushnumber( L, shooting_get_focus_state() );
1137  return 1;
1138}
1139
1140static int luaCB_get_focus_ok( lua_State* L )
1141{
1142  lua_pushnumber( L, shooting_get_focus_ok() );
1143  return 1;
1144}
1145
1146static int luaCB_get_flash_mode( lua_State* L )
1147{
1148  lua_pushnumber( L, shooting_get_flash_mode() );
1149  return 1;
1150}
1151
1152static int luaCB_get_shooting( lua_State* L )
1153{
1154  lua_pushboolean( L, shooting_in_progress() );
1155  return 1;
1156}
1157
1158static int luaCB_get_flash_ready( lua_State* L )
1159{
1160  lua_pushboolean( L, shooting_is_flash() );
1161  return 1;
1162}
1163
1164static int luaCB_get_IS_mode( lua_State* L )
1165{
1166  lua_pushnumber( L, shooting_get_is_mode() );
1167  return 1;
1168}
1169
1170static int luaCB_get_orientation_sensor( lua_State* L )
1171{
1172  lua_pushnumber( L, shooting_get_prop(PROPCASE_ORIENTATION_SENSOR) );
1173  return 1;
1174}
1175
1176static int luaCB_get_zoom_steps( lua_State* L )
1177{
1178  lua_pushnumber( L, zoom_points );
1179  return 1;
1180}
1181
1182static int luaCB_get_nd_present( lua_State* L )
1183{
1184  int to;
1185  #if !CAM_HAS_ND_FILTER
1186  to = 0;
1187  #endif
1188  #if CAM_HAS_ND_FILTER && !CAM_HAS_IRIS_DIAPHRAGM
1189  to = 1;
1190  #endif
1191  #if CAM_HAS_ND_FILTER && CAM_HAS_IRIS_DIAPHRAGM
1192  to = 2;
1193  #endif
1194  lua_pushnumber( L, to );
1195  return 1;
1196}
1197
1198static int luaCB_get_propset( lua_State* L )
1199{
1200  lua_pushnumber( L, CAM_PROPSET );
1201  return 1;
1202}
1203
1204static int luaCB_get_ev( lua_State* L )
1205{
1206  lua_pushnumber( L, shooting_get_ev_correction1() );
1207  return 1;
1208}
1209
1210static int luaCB_set_ev( lua_State* L )
1211{
1212  int to;
1213  to = luaL_checknumber( L, 1 );
1214  shooting_set_prop(PROPCASE_EV_CORRECTION_1, to);
1215  shooting_set_prop(PROPCASE_EV_CORRECTION_2, to);
1216  return 0;
1217}
1218
1219static int luaCB_get_histo_range( lua_State* L )
1220{
1221  int from = (luaL_checknumber(L,1));
1222  int to = (luaL_checknumber(L,2));
1223  if (shot_histogram_isenabled()) lua_pushnumber( L, shot_histogram_get_range(from, to) );
1224  else lua_pushnumber( L, -1 ); // TODO should probably return nil
1225  return 1;
1226}
1227
1228static int luaCB_shot_histo_enable( lua_State* L )
1229{
1230  shot_histogram_set(luaL_checknumber( L, 1 ));
1231  return 0;
1232}
1233
1234static int luaCB_play_sound( lua_State* L )
1235{
1236  play_sound(luaL_checknumber( L, 1 ));
1237  return 0;
1238}
1239
1240static int luaCB_get_temperature( lua_State* L )
1241{
1242  int which = (luaL_checknumber( L, 1 ));
1243  int temp = -100; // do something insane if users passes bad value
1244  switch (which)
1245  {
1246    case 0:
1247      temp = get_optical_temp();
1248      break;
1249    case 1:
1250      temp = get_ccd_temp();
1251      break;
1252    case 2:
1253      temp = get_battery_temp();
1254      break;
1255  }
1256  lua_pushnumber( L, temp );
1257  return 1;
1258}
1259
1260static int luaCB_get_time( lua_State* L )
1261{
1262  int r = -1;
1263  static struct tm *ttm;
1264  ttm = get_localtime();
1265  const char *t = luaL_checkstring( L, 1 );
1266  if (strncmp("s", t, 1)==0) r = ( L, ttm->tm_sec );
1267  else if (strncmp("m", t, 1)==0) r = ( L, ttm->tm_min );
1268  else if (strncmp("h", t, 1)==0) r = ( L, ttm->tm_hour );
1269  else if (strncmp("D", t, 1)==0) r = ( L, ttm->tm_mday );
1270  else if (strncmp("M", t, 1)==0) r = ( L, ttm->tm_mon+1 );
1271  else if (strncmp("Y", t, 1)==0) r = ( L, 1900+ttm->tm_year );
1272  lua_pushnumber( L, r );
1273  return 1;
1274}
1275/*
1276  val=peek(address[,size])
1277  return the value found at address in memory, or nil if address or size is invalid
1278  size is optional 1=byte 2=halfword 4=word. defaults is 4
1279*/
1280static int luaCB_peek( lua_State* L )
1281{
1282  unsigned addr = luaL_checknumber(L,1);
1283  unsigned size = luaL_optnumber(L, 2, 4);
1284  switch(size) {
1285    case 1:
1286      lua_pushnumber( L, *(unsigned char *)(addr) );
1287    break;
1288    case 2:
1289      if (addr & 0x1) {
1290        lua_pushnil(L);
1291      }
1292      else {
1293        lua_pushnumber( L, *(unsigned short *)(addr) );
1294      }
1295    break;
1296    case 4:
1297      if (addr & 0x3) {
1298        lua_pushnil(L);
1299      }
1300      else {
1301        lua_pushnumber( L, *(unsigned *)(addr) );
1302      }
1303    break;
1304    default:
1305      lua_pushnil(L);
1306
1307  }
1308  return 1;
1309}
1310
1311/*
1312  status=poke(address,value[,size])
1313  writes value to address in memory
1314  size is optional 1=byte 2=halfword 4=word. defaults is 4
1315  returns true, or nil if address or size is invalid
1316*/
1317static int luaCB_poke( lua_State* L )
1318{
1319  unsigned addr = luaL_checknumber(L,1);
1320  unsigned val = luaL_checknumber(L,2);
1321  unsigned size = luaL_optnumber(L, 3, 4);
1322  int status = 0;
1323  switch(size) {
1324    case 1:
1325        *(unsigned char *)(addr) = (unsigned char)val;
1326        status=1;
1327    break;
1328    case 2:
1329      if (!(addr & 0x1)) {
1330        *(unsigned short *)(addr) = (unsigned short)val;
1331        status=1;
1332      }
1333    break;
1334    case 4:
1335      if (!(addr & 0x3)) {
1336        *(unsigned *)(addr) = val;
1337        status=1;
1338      }
1339    break;
1340  }
1341  if(status) {
1342    lua_pushboolean(L,1);
1343  }
1344  else {
1345    lua_pushnil(L);
1346  }
1347  return 1;
1348}
1349
1350static int luaCB_bitand( lua_State* L )
1351{
1352  int v1 = (luaL_checknumber(L,1));
1353  int v2 = (luaL_checknumber(L,2));
1354  lua_pushnumber( L, v1 & v2 );
1355  return 1;
1356}
1357
1358static int luaCB_bitor( lua_State* L )
1359{
1360  int v1 = (luaL_checknumber(L,1));
1361  int v2 = (luaL_checknumber(L,2));
1362  lua_pushnumber( L, v1 | v2 );
1363  return 1;
1364}
1365
1366static int luaCB_bitxor( lua_State* L )
1367{
1368  int v1 = (luaL_checknumber(L,1));
1369  int v2 = (luaL_checknumber(L,2));
1370  lua_pushnumber( L, v1 ^ v2 );
1371  return 1;
1372}
1373
1374static int luaCB_bitshl( lua_State* L )
1375{
1376  int val = (luaL_checknumber(L,1));
1377  unsigned shift = (luaL_checknumber(L,2));
1378  lua_pushnumber( L, val << shift );
1379  return 1;
1380}
1381
1382static int luaCB_bitshri( lua_State* L )
1383{
1384  int val = (luaL_checknumber(L,1));
1385  unsigned shift = (luaL_checknumber(L,2));
1386  lua_pushnumber( L, val >> shift );
1387  return 1;
1388}
1389
1390static int luaCB_bitshru( lua_State* L )
1391{
1392  unsigned val = (luaL_checknumber(L,1));
1393  unsigned shift = (luaL_checknumber(L,2));
1394  lua_pushnumber( L, val >> shift );
1395  return 1;
1396}
1397
1398static int luaCB_bitnot( lua_State* L )
1399{
1400  unsigned val = (luaL_checknumber(L,1));
1401  lua_pushnumber( L, ~val );
1402  return 1;
1403}
1404
1405static void set_string_field(lua_State* L, const char *key, const char *val)
1406{
1407  lua_pushstring(L, val);
1408  lua_setfield(L, -2, key);
1409}
1410
1411static void set_number_field(lua_State* L, const char *key, int val)
1412{
1413  lua_pushnumber(L, val);
1414  lua_setfield(L, -2, key);
1415}
1416
1417static int luaCB_get_buildinfo( lua_State* L )
1418{
1419  lua_createtable(L, 0, 9);
1420  set_string_field( L,"platform", PLATFORM );
1421  set_string_field( L,"platsub", PLATFORMSUB );
1422  set_string_field( L,"version", HDK_VERSION );
1423  set_string_field( L,"build_number", BUILD_NUMBER );
1424  set_string_field( L,"build_revision", BUILD_SVNREV );
1425  set_string_field( L,"build_date", __DATE__ );
1426  set_string_field( L,"build_time", __TIME__ );
1427#ifndef CAM_DRYOS
1428  set_string_field( L,"os", "vxworks" );
1429#else
1430  set_string_field( L,"os", "dryos" );
1431#endif
1432  set_number_field( L, "platformid", PLATFORMID );
1433  return 1;
1434}
1435
1436static int luaCB_get_mode( lua_State* L )
1437{
1438  int m = mode_get();
1439  lua_pushboolean( L, (m&MODE_MASK) != MODE_PLAY );
1440  lua_pushboolean( L, MODE_IS_VIDEO(m) );
1441  lua_pushnumber( L, m );
1442  return 3;
1443}
1444
1445// TODO sanity check file ?
1446static int luaCB_set_raw_develop( lua_State* L )
1447{
1448  raw_prepare_develop(luaL_optstring( L, 1, NULL ));
1449  return 0;
1450}
1451
1452static int luaCB_raw_merge_start( lua_State* L )
1453{
1454  int op = luaL_checknumber(L,1);
1455  if (!module_rawop_load())
1456    return luaL_argerror(L,1,"fail to load raw merge module");
1457
1458  if ( API_VERSION_MATCH_REQUIREMENT( librawop->version, 1, 0 ) &&
1459       (op == RAW_OPERATION_SUM || op == RAW_OPERATION_AVERAGE) ) {
1460    librawop->raw_merge_start(op);
1461  }
1462  else {
1463    return luaL_argerror(L,1,"invalid raw merge op");
1464  }
1465  return 0;
1466}
1467
1468// TODO sanity check file ?
1469static int luaCB_raw_merge_add_file( lua_State* L )
1470{
1471  if (!module_rawop_load())
1472    return luaL_argerror(L,1,"fail to load raw merge module");
1473  librawop->raw_merge_add_file(luaL_checkstring( L, 1 ));
1474  return 0;
1475}
1476
1477static int luaCB_raw_merge_end( lua_State* L )
1478{
1479  if (!module_rawop_load())
1480    return luaL_argerror(L,1,"fail to load raw merge module");
1481  librawop->raw_merge_end();
1482  return 0;
1483}
1484
1485// Enable/disable LCD back light (input argument 1/0)
1486static int luaCB_set_backlight( lua_State* L )
1487{
1488  int val = (luaL_checknumber(L,1));
1489
1490  if (val > 0) TurnOnBackLight();
1491  else TurnOffBackLight();
1492  return 0;
1493}
1494
1495// get the string or number passed in index and return it as an event id
1496static unsigned levent_id_from_lua_arg( lua_State* L, int index)
1497{
1498  unsigned event_id;
1499  if (lua_type(L, index) == LUA_TSTRING) {
1500    const char *ev_name = lua_tostring(L, index);
1501        event_id = levent_id_for_name(ev_name);
1502    if (event_id == 0) {
1503        return luaL_error( L, "bad event name '%s'", ev_name );
1504    }
1505  }
1506  // could check here if it is in the table, but even valid ones can crash
1507  // so we avoid searching the table if given a number
1508  else if (lua_type(L,index) == LUA_TNUMBER){
1509        event_id = lua_tonumber(L,index);
1510  }
1511  else {
1512    return luaL_error( L, "expected event name or id" );
1513  }
1514  return event_id;
1515}
1516
1517/*
1518  get a value where boolean or 0/!0 are accepted for on/off.
1519  normal lua toboolean will convert 0 to true, but ubasic and c users
1520  will expect 0 to be off
1521  intentional HACK: numbers greater than 1 are returned as is
1522*/
1523static unsigned on_off_value_from_lua_arg( lua_State* L, int index)
1524{
1525  if( lua_isboolean(L,index) ) {
1526        return lua_toboolean(L,index);
1527  }
1528  else {
1529        return luaL_checknumber(L,index);
1530  }
1531}
1532
1533/*
1534  return the index of an event, given it's name or event id
1535*/
1536static unsigned levent_index_from_id_lua_arg( lua_State* L, int index )
1537{
1538  if (lua_type(L, index) == LUA_TSTRING) {
1539        return levent_index_for_name(lua_tostring(L, index));
1540  }
1541  else if (lua_type(L,index) == LUA_TNUMBER){
1542        return levent_index_for_id(lua_tonumber(L,index));
1543  }
1544  else {
1545    return luaL_error( L, "expected string or number" );
1546  }
1547}
1548
1549/*
1550  name,id,param = get_levent_def(event)
1551  event is an event id (number) or name (string)
1552  returns nil if event is not found
1553*/
1554static int luaCB_get_levent_def( lua_State* L )
1555{
1556  unsigned event_index = levent_index_from_id_lua_arg(L,1);
1557  if (event_index == LEVENT_INVALID_INDEX) {
1558    lua_pushnil(L);
1559    return 1;
1560  }
1561  lua_pushstring(L, levent_table[event_index].name);
1562  lua_pushnumber(L, levent_table[event_index].id);
1563  lua_pushnumber(L, levent_table[event_index].param);
1564  return 3;
1565}
1566
1567/*
1568  index=get_levent_index(event)
1569  event is an event id (number) or name (string)
1570  returns index or nil if not found
1571*/
1572static int luaCB_get_levent_index( lua_State* L )
1573{
1574  unsigned event_index = levent_index_from_id_lua_arg(L,1);
1575  if (event_index == LEVENT_INVALID_INDEX) {
1576    lua_pushnil(L);
1577  }
1578  else {
1579    lua_pushnumber(L, event_index);
1580  }
1581  return 1;
1582}
1583
1584/*
1585  name,id,param = get_levent_def_by_index(event_index)
1586  event_index is number index into the event table
1587  returns nil if event is not found
1588*/
1589static int luaCB_get_levent_def_by_index( lua_State* L )
1590{
1591  unsigned i = luaL_checknumber(L,1);
1592  if(i >= levent_count()) {
1593        lua_pushnil(L);
1594    return 1;
1595  }
1596  lua_pushstring(L, levent_table[i].name);
1597  lua_pushnumber(L, levent_table[i].id);
1598  lua_pushnumber(L, levent_table[i].param);
1599  return 3;
1600}
1601
1602/*
1603  post_levent_*(event[,unk])
1604  post the event with PostLogicalEventToUI or PostLogicaEventForNotPowerType
1605  This sends the event. The difference between functions isn't clear.
1606  event is an event id (number) or name (string).
1607  unk is an optional number whose meaning is unknown, defaults to zero.
1608    Based on code, other values would probably be a pointer.
1609        This is NOT the 3rd item in the event table.
1610*/
1611static int luaCB_post_levent_to_ui( lua_State* L )
1612{
1613  unsigned event_id,arg;
1614
1615  event_id = levent_id_from_lua_arg(L,1);
1616  arg = luaL_optnumber(L, 2, 0);
1617  PostLogicalEventToUI(event_id,arg);
1618  return 0;
1619}
1620
1621static int luaCB_post_levent_for_npt( lua_State* L )
1622{
1623  unsigned event_id,arg;
1624
1625  event_id = levent_id_from_lua_arg(L,1);
1626  arg = luaL_optnumber(L, 2, 0);
1627  PostLogicalEventForNotPowerType(event_id,arg);
1628  return 0;
1629}
1630
1631/*
1632  set_levent_active(event,state)
1633  event is an event id (number) or name (string)
1634  state is a numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
1635  exact meaning is unknown, but it has something to do with the delivery of the specified event.
1636*/
1637static int luaCB_set_levent_active( lua_State* L )
1638{
1639  unsigned event_id;
1640  unsigned state;
1641
1642  event_id = levent_id_from_lua_arg(L,1);
1643  state = on_off_value_from_lua_arg(L,2);
1644  SetLogicalEventActive(event_id,state);
1645  return 0;
1646}
1647
1648/*
1649  set_levent_script_mode(state)
1650  state is numeric or boolean state. true or non zero numbers turn on zero, false or nil turn off
1651  exact meaning is unknown, but it has something to do with the behavior of events and/or SetLogicalEventActive.
1652*/
1653static int luaCB_set_levent_script_mode( lua_State* L )
1654{
1655  SetScriptMode(on_off_value_from_lua_arg(L,1));
1656  return 0;
1657}
1658
1659/*
1660  result=set_capture_mode_canon(value)
1661  where value is a valid PROPCASE_SHOOTING_MODE value for the current camera
1662  result is true if the camera is in rec mode
1663*/
1664static int luaCB_set_capture_mode_canon( lua_State* L )
1665{
1666  int modenum = luaL_checknumber(L,1);
1667  // if the value as negative, assume it is a mistakenly sign extended PROPCASE_SHOOTING_MODE value
1668  if(modenum < 0)
1669    modenum &= 0xFFFF;
1670  lua_pushboolean( L, shooting_set_mode_canon(modenum) );
1671  return 1;
1672}
1673
1674/*
1675 result=set_capture_mode(modenum)
1676 where modenum is a valid CHDK modemap value
1677 result is true if modenum is a valid modemap value, otherwise false
1678*/
1679static int luaCB_set_capture_mode( lua_State* L )
1680{
1681  int modenum = luaL_checknumber(L,1);
1682  lua_pushboolean( L, shooting_set_mode_chdk(modenum) );
1683  return 1;
1684}
1685
1686/*
1687 result=is_capture_mode_valid(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_is_capture_mode_valid( lua_State* L )
1692{
1693  int modenum = luaL_checknumber(L,1);
1694  lua_pushboolean( L, shooting_mode_chdk2canon(modenum) != -1 );
1695  return 1;
1696}
1697
1698/*
1699  set_record(state)
1700  if state is 0 (or false) the camera is set to play mode. If 1 or true, the camera is set to record mode.
1701  NOTE: this only begins the mode change. Script should wait until get_mode() reflects the change,
1702  before doing anything that requires the new mode. e.g.
1703  set_record(true)
1704  while not get_mode() do
1705        sleep(10)
1706  end
1707*/
1708static int luaCB_set_record( lua_State* L )
1709{
1710  if(on_off_value_from_lua_arg(L,1)) {
1711    levent_set_record();
1712  }
1713  else {
1714    levent_set_play();
1715  }
1716  return 0;
1717}
1718
1719// switch mode (0 = playback, 1 = record)
1720// only for when USB is connected
1721static int luaCB_switch_mode_usb( lua_State* L )
1722{
1723  int mode = luaL_checknumber(L,1);
1724
1725  if ( mode != 0 && mode != 1 )
1726  {
1727    return 0;
1728  }
1729
1730  return switch_mode_usb(mode);
1731}
1732 
1733#ifdef CAM_CHDK_PTP
1734// PTP Live View functions
1735
1736// Function used to get viewport, bitmap and palette data via PTP
1737// Address of this function sent back to client program which then
1738// calls this with options to determine what to transfer
1739static int handle_video_transfer(ptp_data *data, int flags, int arg2)
1740{
1741    int total_size;             // Calculated total size of data to transfer to client
1742
1743    // Structure containing the info for the current live view frame
1744    // This information may change across calls
1745    struct {
1746        int vp_xoffset;             // Viewport X offset in pixels (for cameras with variable image size)
1747        int vp_yoffset;             // Viewpoer Y offset in pixels (for cameras with variable image size)
1748        int vp_width;               // Actual viewport width in pixels (for cameras with variable image size)
1749        int vp_height;              // Actual viewport height in pixels (for cameras with variable image size)
1750        int vp_buffer_start;        // Offset in data transferred where the viewport data starts
1751        int vp_buffer_size;         // Size of viewport data sent (in bytes)
1752        int bm_buffer_start;        // Offset in data transferred where the bitmap data starts
1753        int bm_buffer_size;         // Size of bitmap data sent (in bytes)
1754        int palette_type;           // Camera palette type
1755                                    // (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)
1756        int palette_buffer_start;   // Offset in data transferred where the palette data starts
1757        int palette_buffer_size;    // Size of palette data sent (in bytes)
1758    } vid_info;
1759
1760    // Populate the above structure with the current default details
1761    vid_info.vp_xoffset = vid_get_viewport_display_xoffset_proper();
1762    vid_info.vp_yoffset = vid_get_viewport_display_yoffset_proper();
1763    vid_info.vp_width = vid_get_viewport_width_proper();
1764    vid_info.vp_height = vid_get_viewport_height_proper();
1765    vid_info.vp_buffer_start = 0;
1766    vid_info.vp_buffer_size = 0;
1767    vid_info.bm_buffer_start = 0;
1768    vid_info.bm_buffer_size = 0;
1769    vid_info.palette_type = vid_get_palette_type();
1770    vid_info.palette_buffer_start = 0;
1771    vid_info.palette_buffer_size = 0;
1772
1773    total_size = sizeof(vid_info);
1774
1775    // Add viewport details if requested
1776    if ( flags & 0x1 ) // live buffer
1777    {
1778        vid_info.vp_buffer_start = total_size;
1779        vid_info.vp_buffer_size = (vid_get_viewport_buffer_width_proper()*vid_get_viewport_max_height()*6)/4;
1780        total_size += vid_info.vp_buffer_size;
1781    }
1782
1783    // Add bitmap details if requested
1784    if ( flags & 0x4 ) // bitmap buffer
1785    {
1786        vid_info.bm_buffer_start = total_size;
1787        vid_info.bm_buffer_size = camera_screen.buffer_width*camera_screen.height;
1788        total_size += vid_info.bm_buffer_size;
1789    }
1790
1791    // Add palette detals if requested
1792    if ( flags & 0x8 ) // bitmap palette
1793    {
1794        vid_info.palette_buffer_start = total_size;
1795        vid_info.palette_buffer_size = vid_get_palette_size();
1796        total_size += vid_info.palette_buffer_size;
1797    }
1798
1799    // Send header structure (along with total size to be sent)
1800    data->send_data(data->handle,(char*)&vid_info,sizeof(vid_info),total_size,0,0,0);
1801
1802    // Send viewport data if requested
1803    if ( flags & 0x1 )
1804    {
1805        data->send_data(data->handle,vid_get_viewport_active_buffer(),vid_info.vp_buffer_size,0,0,0,0);
1806    }
1807
1808    // Send bitmap data if requested
1809    if ( flags & 0x4 )
1810    {
1811        data->send_data(data->handle,vid_get_bitmap_active_buffer(),vid_info.bm_buffer_size,0,0,0,0);
1812    }
1813
1814    // Send palette data if requested
1815    if ( flags & 0x8 )
1816    {
1817        data->send_data(data->handle,vid_get_bitmap_active_palette(),vid_info.palette_buffer_size,0,0,0,0);
1818    }
1819
1820    return 0;
1821}
1822
1823// Lua function to return base info for PTP live view, including address of above transfer function
1824static int luaCB_get_video_details( lua_State* L )
1825{
1826    // Structure to popualate with live view details
1827    // These details are static and only need to be retrieved once
1828    struct {
1829        int transfer_function;      // Address of transfer function above
1830        int vp_max_width;           // Maximum viewport width (in pixels)
1831        int vp_max_height;          // Maximum viewport height (in pixels)
1832        int vp_buffer_width;        // Viewport buffer width in case buffer is wider than visible viewport (in pixels)
1833        int bm_max_width;           // Maximum width of bitmap (in pixels)
1834        int bm_max_height;          // Maximum height of bitmap (in pixels)
1835        int bm_buffer_width;        // Bitmap buffer width in case buffer is wider than visible bitmap (in pixels)
1836        int lcd_aspect_ratio;       // 0 = 4:3, 1 = 16:9
1837    } details;
1838
1839    // Populate structure info
1840    details.transfer_function = (int) handle_video_transfer;
1841    details.vp_max_width = vid_get_viewport_max_width();
1842    details.vp_max_height = vid_get_viewport_max_height();
1843    details.vp_buffer_width = vid_get_viewport_buffer_width_proper();
1844#if CAM_USES_ASPECT_CORRECTION
1845    details.bm_max_width = ASPECT_XCORRECTION(camera_screen.width);
1846#else
1847    details.bm_max_width = camera_screen.width;
1848#endif
1849    details.bm_max_height = camera_screen.height;
1850    details.bm_buffer_width = camera_screen.buffer_width;
1851    details.lcd_aspect_ratio = vid_get_aspect_ratio();
1852
1853    // Send data back to client
1854    lua_pushlstring( L, (char *) &details, sizeof(details) );
1855
1856    return 1;
1857}
1858#endif
1859
1860/*
1861pack the lua args into a buffer to pass to the native code calling functions
1862currently only handles strings/numbers
1863start is the stack index of the first arg
1864*/
1865#ifdef OPT_LUA_CALL_NATIVE
1866static int pack_native_args( lua_State* L, unsigned start, unsigned *argbuf)
1867{
1868  unsigned i;
1869  unsigned end = lua_gettop(L);
1870
1871  for(i = start; i <= end; i++,argbuf++) {
1872    if (lua_type(L, i) == LUA_TSTRING) {
1873        *argbuf=(unsigned)lua_tostring( L, i);
1874    }
1875    else if (lua_type(L, i) == LUA_TNUMBER) {
1876        *argbuf=lua_tonumber( L, i);
1877    }
1878    else {
1879      return 0;
1880    }
1881  }
1882  return 1;
1883}
1884
1885/*
1886Native function call interface. Can be used to call canon eventprocs or arbitrary
1887pointers.
1888
1889NOTE: this is preliminary, interface may change in later versions!
1890All arguments must be strings or numbers.
1891If the function expects to modify it's arguments via a pointer,
1892then you must provide a number that is a valid pointer.
1893
1894You can use the "AllocateMemory" eventproc to obtain buffers.
1895
1896If the function tries to write to a string passed from lua, Bad Things may happen.
1897
1898This is potentially dangerous, functions exist which can destroy the onboard firmware.
1899*/
1900
1901/*
1902result=call_func_ptr(ptr,...)
1903ptr: address of a valid ARM or Thumb function, which uses the normal C calling convention.
1904result: R0 value after the call returns
1905*/
1906static int luaCB_call_func_ptr( lua_State* L)
1907{
1908  unsigned *argbuf=NULL;
1909  unsigned n_args = lua_gettop(L)-1;
1910  void *fptr;
1911
1912  fptr=(void *)luaL_checknumber( L, 1 );
1913
1914  if (n_args) {
1915    argbuf=malloc(n_args * 4);
1916    if(!argbuf) {
1917      return luaL_error( L, "malloc fail" );
1918    }
1919    if(!pack_native_args(L, 2, argbuf)) {
1920      free(argbuf);
1921      return luaL_error( L, "expected string or number" );
1922    }
1923  }
1924 
1925  lua_pushnumber( L, call_func_ptr(fptr, argbuf, n_args) );
1926  free(argbuf);
1927  return 1;
1928}
1929
1930/*
1931Call an event procedure
1932
1933result=call_event_proc("EventprocName",...)
1934result is the value returned by ExecuteEventProcedure, which is -1 if the eventproc is not found,
1935or the eventproc return value (which could also be -1)
1936NOTE:
1937Many eventprocs are not registered by default, but can be loaded by calling another event proc
1938Some useful ones are
1939SystemEventInit
1940        includes AllocateMemory, FreeMemory, sprintf, memcpy, Fut functions, log ...
1941UI_RegistDebugEventProc
1942        includes capture mode functions, PTM_ functions and much more
1943RegisterProductTestEvent
1944        includes PT_ functions
1945
1946Others:
1947RegisterShootSeqEvent
1948RegisterNRTableEvent
1949*/
1950
1951// grab from lowlevel
1952extern unsigned _ExecuteEventProcedure(const char *name,...);
1953static int luaCB_call_event_proc( lua_State* L )
1954{
1955  const char *evpname;
1956  unsigned *argbuf;
1957  unsigned n_args = lua_gettop(L);
1958
1959  evpname=luaL_checkstring( L, 1 );
1960
1961  argbuf=malloc(n_args * 4);
1962  if (!argbuf) {
1963    return luaL_error( L, "malloc fail" );
1964  }
1965
1966  // event proc name is first arg
1967  *argbuf = (unsigned)evpname;
1968 
1969  if(!pack_native_args(L,2,argbuf+1)) {
1970    free(argbuf);
1971    return luaL_error( L, "expected string or number" );
1972  }
1973 
1974  lua_pushnumber( L, call_func_ptr(_ExecuteEventProcedure,argbuf,n_args) );
1975  free(argbuf);
1976  return 1;
1977}
1978
1979#endif // OPT_LUA_CALL_NATIVE
1980
1981/*
1982result = reboot(["filename"])
1983returns false on failure, does not return on success
1984see lib/armutil/reboot.c for details
1985*/
1986static int luaCB_reboot( lua_State* L )
1987{
1988    lua_pushboolean(L, reboot(luaL_optstring( L, 1, NULL )));
1989    return 1;
1990}
1991
1992static int luaCB_get_config_value( lua_State* L ) {
1993    unsigned int argc = lua_gettop(L);
1994    unsigned int id, i;
1995    int ret = 1;
1996    tConfigVal configVal;
1997   
1998    if( argc>=1 ) {
1999        id = luaL_checknumber(L, 1);
2000        switch( conf_getValue(id, &configVal) ) {
2001            case CONF_VALUE:
2002                lua_pushnumber(L, configVal.numb);
2003            break;
2004            case CONF_INT_PTR:
2005                lua_createtable(L, 0, configVal.numb);
2006                for( i=0; i<configVal.numb; i++ ) {
2007                    lua_pushinteger(L, configVal.pInt[i]);
2008                    lua_rawseti(L, -2, i+1);  //t[i+1]=configVal.pInt[i]
2009                }
2010            break;
2011            case CONF_CHAR_PTR:
2012                lua_pushstring(L, configVal.str);
2013            break;
2014            case CONF_OSD_POS:
2015                lua_pushnumber(L, configVal.pos.x);
2016                lua_pushnumber(L, configVal.pos.y); ret++;
2017            break;
2018            default:
2019                if( argc>=2) { //Default
2020                    ret = argc-1;
2021                } else {
2022                    lua_pushnil(L);
2023                }
2024            break;
2025        }
2026    } else {
2027        lua_pushnil(L);
2028    }
2029    return ret;
2030}
2031
2032static int luaCB_set_config_value( lua_State* L ) {
2033    unsigned int argc = lua_gettop(L);
2034    unsigned int id, i, j;
2035    tConfigVal configVal = {0,0,0,0};  //initialize isXXX
2036   
2037    if( argc>=2 ) {
2038        id = luaL_checknumber(L, 1);
2039        for( i=2; i<=argc; i++) {
2040            switch( lua_type(L, i) ) {
2041                case LUA_TNUMBER:
2042                    if( !configVal.isNumb ) {
2043                        configVal.numb = luaL_checknumber(L, i);
2044                        configVal.isNumb++;
2045                    }
2046                    switch( configVal.isPos ) {
2047                        case 0: configVal.pos.x = luaL_checknumber(L, i); configVal.isPos++; break;
2048                        case 1: configVal.pos.y = luaL_checknumber(L, i); configVal.isPos++; break;
2049                    }
2050                break;
2051                case LUA_TSTRING:
2052                    if( !configVal.isStr ) {
2053                        configVal.str = (char*)luaL_checkstring(L, i);
2054                        configVal.isStr++;
2055                    }
2056                break;
2057                case LUA_TTABLE:
2058                    if( !configVal.isPInt ) {
2059                        configVal.numb = lua_objlen(L, i);
2060                        if( configVal.pInt ) {
2061                            free(configVal.pInt);
2062                            configVal.pInt = NULL;
2063                        }
2064                        configVal.pInt = malloc(configVal.numb*sizeof(int));
2065                        if( configVal.pInt ) {
2066                            for( j=1; j<=configVal.numb; j++) {
2067                                lua_rawgeti(L, i, j);
2068                                configVal.pInt[j-1] = lua_tointeger(L, -1);
2069                                lua_pop(L, 1);
2070                            }
2071                        }
2072                        configVal.isPInt++;
2073                    }
2074                break;
2075            }
2076        }
2077        lua_pushboolean(L, conf_setValue(id, configVal));
2078        if( configVal.pInt ) {
2079            free(configVal.pInt);
2080            configVal.pInt = NULL;
2081        }
2082    } else lua_pushboolean(L, 0);
2083    return 1;
2084}
2085
2086static int luaCB_set_file_attributes( lua_State* L ) {
2087    unsigned int argc = lua_gettop(L);
2088    if( argc>=2 ) {
2089        lua_pushnumber(L, SetFileAttributes(luaL_checkstring(L, 1), luaL_checknumber(L, 2)));
2090    }
2091    return 1;
2092}
2093
2094#ifdef CAM_CHDK_PTP
2095/*
2096msg = read_usb_msg([timeout])
2097read a message from the CHDK ptp interface.
2098Returns the next available message as a string, or nil if no messages are available
2099If timeout is given and not zero, wait until a message is available or timeout expires
2100*/
2101static int luaCB_read_usb_msg( lua_State* L )
2102{
2103  int timeout = luaL_optnumber( L, 1, 0 );
2104  if(timeout) {
2105    action_push(timeout);
2106    action_push(AS_SCRIPT_READ_USB_MSG);
2107    return lua_yield( L, 0 );
2108  }
2109  ptp_script_msg *msg = ptp_script_read_msg();
2110  if(msg) {
2111    lua_pushlstring(L,msg->data,msg->size);
2112    return 1;
2113  }
2114  lua_pushnil(L);
2115  return 1;
2116}
2117
2118/*
2119status = write_usb_msg(msg,[timeout])
2120writes a message to the CHDK ptp interface
2121msg may be nil, boolean, number, string or table (table has some restrictions, will be converted to string)
2122returns true if the message was queued successfully, otherwise false
2123if timeout is set and not zero, wait until message is written or timeout expires
2124NOTE strings will not include a terminating NULL, must be handled by recipient
2125*/
2126static int luaCB_write_usb_msg( lua_State* L )
2127{
2128  ptp_script_msg *msg;
2129  int timeout = luaL_optnumber( L, 2, 0 );
2130  // TODO would it be better to either ignore this or return nil ?
2131  // a write_usb_msg(function_which_returns_no_value()) is an error in this case
2132  // replacing with nil might be more luaish
2133  if(lua_gettop(L) < 1) {
2134    return luaL_error(L,"missing argument");
2135  }
2136  msg=lua_create_usb_msg(L,1,PTP_CHDK_S_MSGTYPE_USER);
2137  // for user messages, trying to create a message from an incompatible type throws an error
2138  if(msg->subtype == PTP_CHDK_TYPE_UNSUPPORTED) {
2139    free(msg);
2140    return luaL_error(L,"unsupported type");
2141  }
2142  if(!msg) {
2143    return luaL_error(L,"failed to create message");
2144  }
2145  if(timeout) {
2146    action_push(timeout);
2147    action_push((int)msg);
2148    action_push(AS_SCRIPT_WRITE_USB_MSG);
2149    return lua_yield( L, 0 );
2150  }
2151  lua_pushboolean(L,ptp_script_write_msg(msg));
2152  return 1;
2153}
2154#endif
2155
2156/* helper for meminfo to set table field only if valid */
2157static void set_meminfo_num( lua_State* L,const char *name, int val) {
2158    if(val != -1) {
2159        set_number_field( L, name, val );
2160    }
2161}
2162/*
2163meminfo=get_meminfo([heapname])
2164get camera memory information
2165heapname="system" or "exmem" if not given, meminfo is returned for heap used by CHDK for malloc
2166meminfo is false if the requested heapname isn't valid ("exmem" when exmem is not enabled, or unknown)
2167otherwise, a table of the form
2168meminfo = {
2169    name -- string "system" or "exmem"
2170    chdk_malloc -- bool, this is the heap used by CHDK for malloc
2171    chdk_start -- number, load address of CHDK
2172    chdk_size -- number, size of CHDK image
2173    -- all the following are numbers, will not be set if not available
2174    start_address
2175    end_address
2176    total_size
2177    allocated_size
2178    allocated_peak
2179    allocated_count
2180    free_size
2181    free_block_max_size
2182    free_block_count
2183}
2184NOTES
2185* under vxworks and cameras without GetMemInfo only the only valid fields
2186  for the system heap will be those defined by chdk and free_block_max_size
2187* the meaning of fields may not correspond exactly between exmem and system
2188*/
2189static int luaCB_get_meminfo( lua_State* L ) {
2190    // for memory info, duplicated from lowlevel
2191    extern const char _start,_end;
2192
2193#if defined(OPT_EXMEM_MALLOC) && !defined(OPT_EXMEM_TESTING)
2194    const char *default_heapname="exmem";
2195#else
2196    const char *default_heapname="system";
2197#endif
2198    const char *heapname = luaL_optstring( L, 1, default_heapname );
2199    cam_meminfo meminfo;
2200
2201    if(strcmp(heapname,"system") == 0) {
2202        GetMemInfo(&meminfo);
2203    }
2204#if defined(OPT_EXMEM_MALLOC) && !defined(OPT_EXMEM_TESTING)
2205    else if(strcmp(heapname,"exmem") == 0) {
2206        GetExMemInfo(&meminfo);
2207        meminfo.allocated_count = -1; // not implemented in suba
2208    }
2209#endif
2210    else {
2211        lua_pushboolean(L,0);
2212        return 1;
2213    }
2214    // adjust start and size, if CHDK is loaded at heap start
2215    if(meminfo.start_address == (int)(&_start)) {
2216        meminfo.start_address += MEMISOSIZE;
2217        meminfo.total_size -= MEMISOSIZE;
2218    }
2219    lua_createtable(L, 0, 13); // might not always use 13, but doesn't hurt
2220    set_string_field( L,"name", heapname );
2221    lua_pushboolean( L, (strcmp(heapname,default_heapname)==0));
2222    lua_setfield(L, -2, "chdk_malloc");
2223    set_number_field( L, "chdk_start", (int)(&_start) );
2224    set_number_field( L, "chdk_size", MEMISOSIZE );
2225    set_meminfo_num( L, "start_address", meminfo.start_address );
2226    set_meminfo_num( L, "end_address", meminfo.end_address);
2227    set_meminfo_num( L, "total_size", meminfo.total_size);
2228    set_meminfo_num( L, "allocated_size", meminfo.allocated_size);
2229    set_meminfo_num( L, "allocated_peak", meminfo.allocated_peak);
2230    set_meminfo_num( L, "allocated_count", meminfo.allocated_count);
2231    set_meminfo_num( L, "free_size", meminfo.free_size);
2232    set_meminfo_num( L, "free_block_max_size", meminfo.free_block_max_size);
2233    set_meminfo_num( L, "free_block_count", meminfo.free_block_count);
2234    return 1;
2235}
2236
2237/*
2238set scheduling parameters
2239old_max_count,old_max_ms=set_yield(max_count,max_ms)
2240*/
2241static int luaCB_set_yield( lua_State* L )
2242{
2243  lua_pushnumber(L,yield_max_count);
2244  lua_pushnumber(L,yield_max_ms);
2245  yield_max_count = luaL_optnumber(L,1,YIELD_MAX_COUNT_DEFAULT);
2246  yield_max_ms = luaL_optnumber(L,2,YIELD_MAX_MS_DEFAULT);
2247  return 2;
2248}
2249
2250static void register_func( lua_State* L, const char *name, void *func) {
2251  lua_pushcfunction( L, func );
2252  lua_setglobal( L, name );
2253}
2254
2255#define FUNC( X ) { #X, luaCB_##X },
2256static const luaL_Reg chdk_funcs[] = {
2257    FUNC(shoot)
2258    FUNC(sleep)
2259    FUNC(cls)
2260    FUNC(set_console_layout)
2261    FUNC(set_console_autoredraw)
2262    FUNC(console_redraw)
2263    FUNC(get_av96)
2264    FUNC(get_bv96)
2265    FUNC(get_day_seconds)
2266    FUNC(get_disk_size)
2267    FUNC(get_dofinfo)
2268    FUNC(get_free_disk_space)
2269    FUNC(get_focus)
2270    FUNC(get_iso_market)
2271    FUNC(get_iso_mode)
2272    FUNC(get_iso_real)
2273    FUNC(get_jpg_count)
2274    FUNC(get_prop)
2275    FUNC(get_prop_str)
2276    FUNC(get_raw_count)
2277    FUNC(get_raw_nr)
2278    FUNC(get_raw)
2279    FUNC(get_sv96)
2280    FUNC(get_tick_count)
2281    FUNC(get_tv96)
2282    FUNC(get_user_av_id)
2283    FUNC(get_user_av96)
2284    FUNC(get_user_tv_id)
2285    FUNC(get_user_tv96)
2286    FUNC(get_vbatt)
2287    FUNC(get_zoom)
2288    FUNC(get_exp_count)
2289    FUNC(get_flash_params_count)
2290    FUNC(get_parameter_data)
2291
2292    FUNC(set_av96_direct)
2293    FUNC(set_av96)
2294    FUNC(set_focus)
2295    FUNC(set_iso_mode)
2296    FUNC(set_iso_real)
2297    FUNC(set_led)
2298    FUNC(set_nd_filter)
2299    FUNC(set_prop)
2300    FUNC(set_prop_str)
2301    FUNC(set_raw_nr)
2302    FUNC(set_raw)
2303    FUNC(set_sv96)
2304    FUNC(set_tv96_direct)
2305    FUNC(set_tv96)
2306    FUNC(set_user_av_by_id_rel)
2307    FUNC(set_user_av_by_id)
2308    FUNC(set_user_av96)
2309    FUNC(set_user_tv_by_id_rel)
2310    FUNC(set_user_tv_by_id)
2311    FUNC(set_user_tv96)
2312    FUNC(set_zoom_speed)
2313    FUNC(set_zoom_rel)
2314    FUNC(set_zoom)
2315
2316    FUNC(wait_click)
2317    FUNC(is_pressed)
2318    FUNC(is_key)
2319#ifdef CAM_HAS_JOGDIAL
2320    FUNC(wheel_right)
2321    FUNC(wheel_left)
2322#endif
2323    FUNC(md_get_cell_diff)
2324    FUNC(md_detect_motion)
2325    FUNC(autostarted)
2326    FUNC(get_autostart)
2327    FUNC(set_autostart)
2328    FUNC(get_usb_power)
2329    FUNC(enter_alt)
2330    FUNC(exit_alt)
2331    FUNC(shut_down)
2332    FUNC(print_screen)
2333
2334#ifdef CAM_MULTIPART
2335    FUNC(get_partitionInfo)
2336    FUNC(swap_partitions)
2337#endif
2338
2339    FUNC(get_focus_mode)
2340    FUNC(get_focus_state)
2341    FUNC(get_focus_ok)
2342    FUNC(get_propset)
2343    FUNC(get_zoom_steps)
2344    FUNC(get_drive_mode)
2345    FUNC(get_flash_mode)
2346    FUNC(get_shooting)
2347    FUNC(get_flash_ready)
2348    FUNC(get_IS_mode)
2349    FUNC(set_ev)
2350    FUNC(get_ev)
2351    FUNC(get_orientation_sensor)
2352    FUNC(get_nd_present)
2353    FUNC(get_movie_status)
2354    FUNC(set_movie_status)
2355 
2356    FUNC(get_histo_range)
2357    FUNC(shot_histo_enable)
2358    FUNC(play_sound)
2359    FUNC(get_temperature)
2360    FUNC(peek)
2361    FUNC(poke)
2362    FUNC(bitand)
2363    FUNC(bitor)
2364    FUNC(bitxor)
2365    FUNC(bitshl)
2366    FUNC(bitshri)
2367    FUNC(bitshru)
2368    FUNC(bitnot)
2369
2370    FUNC(get_time)
2371
2372    FUNC(get_buildinfo)
2373    FUNC(get_mode)
2374
2375    FUNC(set_raw_develop)
2376    // NOTE these functions normally run in the spytask.
2377    // called from lua they will run from kbd task instead
2378    FUNC(raw_merge_start)
2379    FUNC(raw_merge_add_file)
2380    FUNC(raw_merge_end)
2381    FUNC(set_backlight)
2382    FUNC(set_aflock)
2383#ifdef OPT_CURVES
2384    FUNC(set_curve_state)
2385    FUNC(get_curve_state)
2386    FUNC(set_curve_file)
2387    FUNC(get_curve_file)
2388#endif
2389    // get levent definition by name or id, nil if not found
2390    FUNC(get_levent_def)
2391    // get levent definition by index, nil if out of range
2392    FUNC(get_levent_def_by_index)
2393    // get levent index from name or ID
2394    FUNC(get_levent_index)
2395    FUNC(post_levent_to_ui)
2396    FUNC(post_levent_for_npt)
2397    FUNC(set_levent_active)
2398    FUNC(set_levent_script_mode)
2399
2400    FUNC(set_capture_mode)
2401    FUNC(set_capture_mode_canon)
2402    FUNC(is_capture_mode_valid)
2403
2404    FUNC(set_record)
2405
2406    FUNC(switch_mode_usb)
2407#ifdef CAM_CHDK_PTP
2408   FUNC(get_video_details)
2409#endif
2410
2411#ifdef OPT_LUA_CALL_NATIVE
2412    FUNC(call_event_proc)
2413    FUNC(call_func_ptr)
2414#endif
2415    FUNC(reboot)
2416    FUNC(get_config_value)
2417    FUNC(set_config_value)
2418    FUNC(set_file_attributes)
2419    FUNC(get_meminfo)
2420    FUNC(file_browser)
2421    FUNC(textbox)
2422    FUNC(draw_pixel)
2423    FUNC(draw_line)
2424    FUNC(draw_rect)
2425    FUNC(draw_rect_filled)
2426    FUNC(draw_ellipse)
2427    FUNC(draw_ellipse_filled)
2428    FUNC(draw_clear)
2429    FUNC(draw_string)
2430    FUNC(set_yield)
2431#ifdef CAM_CHDK_PTP
2432    FUNC(read_usb_msg)
2433    FUNC(write_usb_msg)
2434#endif
2435    {NULL, NULL},
2436};
2437
2438void register_lua_funcs( lua_State* L )
2439{
2440  const luaL_reg *r;
2441  lua_pushlightuserdata( L, action_push_click );
2442  lua_pushcclosure( L, luaCB_keyfunc, 1 );
2443  lua_setglobal( L, "click" );
2444
2445  lua_pushlightuserdata( L, action_push_press );
2446  lua_pushcclosure( L, luaCB_keyfunc, 1 );
2447  lua_setglobal( L, "press" );
2448
2449  lua_pushlightuserdata( L, action_push_release );
2450  lua_pushcclosure( L, luaCB_keyfunc, 1 );
2451  lua_setglobal( L, "release" );
2452
2453  for(r=chdk_funcs;r->name;r++) {
2454    lua_pushcfunction( L, r->func );
2455    lua_setglobal( L, r->name );
2456  }
2457#ifdef CAM_CHDK_PTP
2458   luaL_dostring(L,"function usb_msg_table_to_string(t)"
2459                    " local v2s=function(v)"
2460                        " local t=type(v)"
2461                        " if t=='string' then return v end"
2462                        " if t=='number' or t=='boolean' or t=='nil' then return tostring(v) end"
2463                        " return '' end"
2464                    " local r=''"
2465                    " for k,v in pairs(t) do"
2466                        " local s,vs=''"
2467                        " if type(v)=='table' then"
2468                            " for i=1,table.maxn(v) do"
2469                            " s=s..'\\t'..v2s(v[i]) end"
2470                        " else"
2471                            " vs=v2s(v)"
2472                            " if #vs then s=s..'\\t'..vs end"
2473                        " end"
2474                        " vs=v2s(k)"
2475                        " if #vs>0 and #s>0 then r=r..vs..s..'\\n' end"
2476                    " end"
2477                    " return r"
2478                   " end");
2479
2480#endif
2481}
Note: See TracBrowser for help on using the repository browser.