Changeset 1083
- Timestamp:
- 03/07/11 04:46:52 (2 years ago)
- Location:
- branches/reyalp-ptp
- Files:
-
- 9 edited
- 1 copied
-
. (copied) (copied from trunk)
-
core/action_stack.c (modified) (3 diffs)
-
core/action_stack.h (modified) (2 diffs)
-
core/luascript.c (modified) (5 diffs)
-
core/luascript.h (modified) (2 diffs)
-
core/ptp.c (modified) (11 diffs)
-
core/ptp.h (modified) (3 diffs)
-
core/script.c (modified) (5 diffs)
-
include/platform.h (modified) (1 diff)
-
include/script.h (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/reyalp-ptp/core/action_stack.c
r1050 r1083 169 169 } 170 170 171 // handle initializing and checking a timeout value on the stack 172 // p is the how far up the stack the timout value is 173 // returns zero if the timeout has not expired, 1 if it has 174 // does not pop the delay value off the stack or clear the delay value 175 int action_process_delay(int p) 176 { 177 int t = get_tick_count(); 178 // FIXME take care if overflow occurs 179 if (action_stacks[active_stack]->delay_target_ticks == 0) 180 { 181 /* setup timer */ 182 action_stacks[active_stack]->delay_target_ticks = t+action_get_prev(p); 183 return 0; 184 } 185 if (action_stacks[active_stack]->delay_target_ticks <= t) 186 { 187 return 1; 188 } 189 return 0; 190 } 191 192 void action_clear_delay(void) 193 { 194 action_stacks[active_stack]->delay_target_ticks = 0; 195 } 196 171 197 // Defines some standard operations. Returns false if it could not process anything. 172 198 // Can only be called from an action stack … … 188 214 break; 189 215 case AS_SLEEP: 190 t = get_tick_count(); 191 // FIXME take care if overflow occurs 192 if (action_stacks[active_stack]->delay_target_ticks == 0) 193 { 194 /* setup timer */ 195 action_stacks[active_stack]->delay_target_ticks = t+action_get_prev(2); 196 } 197 else 198 { 199 if (action_stacks[active_stack]->delay_target_ticks <= t) 200 { 201 action_stacks[active_stack]->delay_target_ticks = 0; 202 203 // pop sleep op. 204 action_pop(); 205 action_pop(); 206 } 216 if(action_process_delay(2)) 217 { 218 action_clear_delay(); 219 action_pop(); 220 action_pop(); 207 221 } 208 222 break; … … 239 253 break; 240 254 case AS_WAIT_CLICK: 241 t = get_tick_count(); 242 if (action_stacks[active_stack]->delay_target_ticks == 0) 243 { 244 /* setup timer */ 245 action_stacks[active_stack]->delay_target_ticks = t+((action_get_prev(2))?action_get_prev(2):86400000); 246 } 247 else 248 { 249 kbd_last_clicked = kbd_get_clicked_key(); 250 if (kbd_last_clicked || (action_stacks[active_stack]->delay_target_ticks <= t)) 251 { 252 if (!kbd_last_clicked) 253 kbd_last_clicked=0xFFFF; 254 255 action_stacks[active_stack]->delay_target_ticks = 0; 256 257 // pop up 258 action_pop(); 259 action_pop(); 260 } 255 if(action_process_delay(2) || (kbd_last_clicked = kbd_get_clicked_key())) 256 { 257 if (!kbd_last_clicked) 258 kbd_last_clicked=0xFFFF; 259 action_clear_delay(); 260 action_pop(); 261 action_pop(); 261 262 } 262 263 break; -
branches/reyalp-ptp/core/action_stack.h
r1032 r1083 19 19 AS_WAIT_CLICK, 20 20 AS_SCRIPT_RUN, 21 AS_MOTION_DETECTOR 21 AS_MOTION_DETECTOR, 22 AS_SCRIPT_READ_USB_MSG, // params: timeout 23 AS_SCRIPT_WRITE_USB_MSG, // params: timeout, size, &data 22 24 }; 23 25 … … 32 34 void action_wait_for_click(int timeout); 33 35 void action_pop(); 36 int action_process_delay(int p); 37 void action_clear_delay(void); 34 38 long action_get_prev(int p); 35 39 int action_stack_standard(long p); -
branches/reyalp-ptp/core/luascript.c
r1036 r1083 15 15 #include "action_stack.h" 16 16 #include "motion_detector.h" 17 #include "ptp.h" 17 18 18 19 #include "../lib/lua/lstate.h" // for L->nCcalls, baseCcalls … … 20 21 lua_State* L; 21 22 lua_State* Lt; 22 int lua_keep_result; 23 24 void *lua_consume_result() 25 { 26 lua_State* r = L; 23 24 static int lua_script_is_ptp; 25 static int yield_hook_enabled; 26 27 static void lua_script_disable_yield_hook(void) { 28 yield_hook_enabled = 0; 29 } 30 static void lua_script_enable_yield_hook(void) { 31 yield_hook_enabled = 1; 32 } 33 34 // create a ptp message from the given stack index 35 // incompatible types will return a TYPE_UNSUPPORTED message 36 static ptp_script_msg *lua_create_usb_msg( lua_State* L, int index, unsigned msgtype) { 37 // TODO maybe we should just pass the lua type constants 38 unsigned datatype, datasize = 4; 39 int ivalue = 0; 40 void *data = &ivalue; 41 int ltype = lua_type(L,index); 42 switch(ltype) { 43 case LUA_TNONE: 44 return NULL; // nothing on the stack, no message generated 45 break; 46 case LUA_TNIL: 47 datatype = PTP_CHDK_TYPE_NIL; 48 break; 49 case LUA_TBOOLEAN: 50 datatype = PTP_CHDK_TYPE_BOOLEAN; 51 ivalue = lua_toboolean(L,index); 52 break; 53 case LUA_TNUMBER: 54 datatype = PTP_CHDK_TYPE_INTEGER; 55 ivalue = lua_tonumber(L,index); 56 break; 57 case LUA_TSTRING: 58 datatype = PTP_CHDK_TYPE_STRING; 59 data = (char *)lua_tolstring(L,index,&datasize); 60 break; 61 // TODO this converts to a string and returns as STRING, format as described at 62 // http://chdk.setepontos.com/index.php?topic=4338.msg62606#msg62606 63 // for compatibility with current PTPCAM/PTPCAMGUI implementation 64 // later we should switch to a proper serialized table with it's own return type 65 case LUA_TTABLE: 66 lua_script_disable_yield_hook(); // don't want to yeild while converting 67 lua_getglobal(L, "usb_msg_table_to_string"); // push function 68 lua_pushvalue(L, index); // copy specified index to top of stack 69 lua_pcall(L,1,1,0); // this will leave an error message as a string on the stack if call fails 70 lua_script_enable_yield_hook(); 71 // an empty table will be returned as an empty string 72 // a non-string should never show up here 73 if ( !(lua_isstring(L,-1) /*&& ( lua_objlen(L,-1) > 0 )*/)) { 74 return NULL; 75 } 76 datatype = PTP_CHDK_TYPE_STRING; 77 data = (char *)lua_tolstring(L,-1,&datasize); 78 lua_pop(L,1); 79 break; 80 default: 81 datatype = PTP_CHDK_TYPE_UNSUPPORTED; 82 data = (char *)lua_typename(L,ltype); // return type name as message data 83 datasize = strlen(data); 84 } 85 return ptp_script_create_msg(msgtype,datatype,datasize,data); 86 } 87 88 void lua_script_reset() 89 { 90 lua_close( L ); 27 91 L = 0; 28 return r;29 }30 31 void lua_script_reset()32 {33 if ( !lua_keep_result )34 {35 lua_close( L );36 L = 0;37 }38 Lt = 0;39 92 } 40 93 41 94 static void lua_count_hook(lua_State *L, lua_Debug *ar) 42 95 { 43 if( L->nCcalls <= L->baseCcalls )96 if( L->nCcalls <= L->baseCcalls && yield_hook_enabled ) 44 97 lua_yield( L, 0 ); 45 98 } 46 99 47 int lua_script_start( char const* script ) 48 { 49 lua_keep_result = 0; 100 void lua_script_error(lua_State *Lt,int runtime) 101 { 102 const char *err = lua_tostring( Lt, -1 ); 103 script_console_add_line( err ); 104 if(runtime) { 105 if(lua_script_is_ptp) { 106 ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, err); 107 script_end(); 108 } else if(conf.debug_lua_restart_on_error) { 109 lua_script_reset(); 110 script_start_gui(0); 111 } else { 112 script_wait_and_end(); 113 } 114 } else { 115 if(lua_script_is_ptp) { 116 ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_COMPILE, err); 117 lua_script_reset(); 118 } else { 119 script_print_screen_end(); 120 script_wait_and_end(); 121 } 122 } 123 } 124 125 126 // TODO more stuff from script.c should be moved here 127 void lua_script_finish(lua_State *L) 128 { 129 if(lua_script_is_ptp) { 130 // send all return values as RET messages 131 int i,end = lua_gettop(L); 132 for(i=1;i<=end; i++) { 133 // if the queue is full return values will be silently discarded 134 // incompatible types will be returned as TYPE_UNSUPPORTED to preserve expected number and order of return values 135 ptp_script_write_msg(lua_create_usb_msg(L,i,PTP_CHDK_S_MSGTYPE_RET)); 136 } 137 } 138 } 139 140 int lua_script_start( char const* script, int ptp ) 141 { 142 lua_script_is_ptp = ptp; 50 143 L = lua_open(); 51 144 luaL_openlibs( L ); … … 55 148 lua_setfield( L, LUA_REGISTRYINDEX, "Lt" ); 56 149 if( luaL_loadstring( Lt, script ) != 0 ) { 57 script_console_add_line( lua_tostring( Lt, -1 ) ); 58 lua_script_reset(); 150 lua_script_error(Lt,0); 59 151 return 0; 60 152 } 61 153 lua_sethook(Lt, lua_count_hook, LUA_MASKCOUNT, 1000 ); 154 lua_script_enable_yield_hook(); 62 155 return 1; 63 156 } … … 1387 1480 return 1; 1388 1481 } 1482 1483 #ifdef CAM_CHDK_PTP 1484 /* 1485 msg = read_usb_msg([timeout]) 1486 read a message from the CHDK ptp interface. 1487 Returns the next available message as a string, or nil if no messages are available 1488 If timeout is given and not zero, wait until a message is available or timeout expires 1489 */ 1490 static int luaCB_read_usb_msg( lua_State* L ) 1491 { 1492 int timeout = luaL_optnumber( L, 1, 0 ); 1493 if(timeout) { 1494 action_push(timeout); 1495 action_push(AS_SCRIPT_READ_USB_MSG); 1496 return lua_yield( L, 0 ); 1497 } 1498 ptp_script_msg *msg = ptp_script_read_msg(); 1499 if(msg) { 1500 lua_pushlstring(L,msg->data,msg->size); 1501 return 1; 1502 } 1503 lua_pushnil(L); 1504 return 1; 1505 } 1506 1507 /* 1508 status = write_usb_msg(msg,[timeout]) 1509 writes a message to the CHDK ptp interface 1510 msg may be nil, boolean, number, string or table (table has some restrictions, will be converted to string) 1511 returns true if the message was queued successfully, otherwise false 1512 if timeout is set and not zero, wait until message is written or timeout expires 1513 NOTE strings will not include a terminating NULL, must be handled by recipient 1514 */ 1515 static int luaCB_write_usb_msg( lua_State* L ) 1516 { 1517 ptp_script_msg *msg; 1518 int timeout = luaL_optnumber( L, 2, 0 ); 1519 // TODO would it be better to either ignore this or return nil ? 1520 // a write_usb_msg(function_which_returns_no_value()) is an error in this case 1521 // replacing with nil might be more luaish 1522 if(lua_gettop(L) < 1) { 1523 return luaL_error(L,"missing argument"); 1524 } 1525 msg=lua_create_usb_msg(L,1,PTP_CHDK_S_MSGTYPE_USER); 1526 // for user messages, trying to create a message from an incompatible type throws an error 1527 if(msg->subtype == PTP_CHDK_TYPE_UNSUPPORTED) { 1528 free(msg); 1529 return luaL_error(L,"unsupported type"); 1530 } 1531 if(!msg) { 1532 return luaL_error(L,"failed to create message"); 1533 } 1534 if(timeout) { 1535 action_push(timeout); 1536 action_push((int)msg); 1537 action_push(AS_SCRIPT_WRITE_USB_MSG); 1538 return lua_yield( L, 0 ); 1539 } 1540 lua_pushboolean(L,ptp_script_write_msg(msg)); 1541 return 1; 1542 } 1543 #endif 1389 1544 1390 1545 void register_lua_funcs( lua_State* L ) … … 1554 1709 #endif 1555 1710 FUNC(reboot); 1556 } 1711 #ifdef CAM_CHDK_PTP 1712 FUNC(read_usb_msg); 1713 FUNC(write_usb_msg); 1714 luaL_dostring(L,"function usb_msg_table_to_string(t)" 1715 " local v2s=function(v)" 1716 " local t=type(v)" 1717 " if t=='string' then return v end" 1718 " if t=='number' or t=='boolean' or t=='nil' then return tostring(v) end" 1719 " return '' end" 1720 " local r=''" 1721 " for k,v in pairs(t) do" 1722 " local s,vs=''" 1723 " if type(v)=='table' then" 1724 " for i=1,table.maxn(v) do" 1725 " s=s..'\\t'..v2s(v[i]) end" 1726 " else" 1727 " vs=v2s(v)" 1728 " if #vs then s=s..'\\t'..vs end" 1729 " end" 1730 " vs=v2s(k)" 1731 " if #vs>0 and #s>0 then r=r..vs..s..'\\n' end" 1732 " end" 1733 " return r" 1734 " end"); 1735 1736 #endif 1737 } -
branches/reyalp-ptp/core/luascript.h
r1021 r1083 4 4 #include "lua.h" 5 5 6 void *lua_consume_result();7 6 void lua_script_reset(); 8 int lua_script_start( char const* script ); 7 int lua_script_start( char const* script,int is_ptp ); 8 void lua_script_error( lua_State* L,int runtime ); 9 void lua_script_finish( lua_State* L ); 9 10 extern void register_lua_funcs( lua_State* L ); 10 11 // run the "restore" function at the end of a script … … 13 14 extern lua_State* L; 14 15 extern lua_State* Lt; 15 extern int lua_keep_result;16 16 17 17 #endif -
branches/reyalp-ptp/core/ptp.c
r1078 r1083 14 14 #include "script.h" 15 15 #include "action_stack.h" 16 17 static lua_State *get_lua_thread(lua_State *L) 18 { 19 lua_State *Lt; 20 21 lua_getfield(L,LUA_REGISTRYINDEX,"Lt"); 22 Lt = lua_tothread(L,-1); 23 lua_pop(L,1); 24 25 return Lt; 26 } 16 // process id for scripts, increments before each attempt to run script 17 // does not handle wraparound 18 static unsigned script_run_id; 27 19 #endif 28 20 … … 64 56 65 57 return 1; 58 } 59 60 // camera will shut down if you ignore a recv data phase 61 static void flush_recv_ptp_data(ptp_data *data,int size) { 62 char *buf; 63 buf = malloc((size > buf_size) ? buf_size:size); 64 if(!buf) // buf_size should always be less then available memory 65 return; 66 while ( size > 0 ) 67 { 68 if ( size >= buf_size ) 69 { 70 recv_ptp_data(data,buf,buf_size); 71 size -= buf_size; 72 } else { 73 recv_ptp_data(data,buf,size); 74 size = 0; 75 } 76 } 77 free(buf); 66 78 } 67 79 … … 94 106 } 95 107 108 #ifdef OPT_LUA 109 // TODO this could be a generic ring buffer of words 110 #define PTP_SCRIPT_MSG_Q_LEN 16 111 typedef struct { 112 unsigned r; // index of current read value 113 unsigned w; // index of next write value, if w == r, empty TODO "full" currently wastes a slot 114 ptp_script_msg *q[PTP_SCRIPT_MSG_Q_LEN]; 115 } ptp_script_msg_q; 116 117 // TODO it would be better to allocate these only when needed 118 ptp_script_msg_q msg_q_in; // messages to pc from script 119 ptp_script_msg_q msg_q_out; // messages to script from pc 120 121 unsigned script_msg_q_next(unsigned i) { 122 if(i == PTP_SCRIPT_MSG_Q_LEN - 1) { 123 return 0; 124 } 125 return i+1; 126 } 127 128 unsigned script_msg_q_full(ptp_script_msg_q *q) { 129 return (script_msg_q_next(q->w) == q->r); 130 } 131 132 unsigned script_msg_q_empty(ptp_script_msg_q *q) { 133 return (q->w == q->r); 134 } 135 136 int enqueue_script_msg(ptp_script_msg_q *q,ptp_script_msg *msg) { 137 unsigned w = script_msg_q_next(q->w); 138 if(w == q->r) { 139 return 0; 140 } 141 // zero size messages don't make any sense 142 if(msg == NULL || msg->size == 0) { 143 return 0; 144 } 145 q->q[q->w] = msg; 146 q->w = w; 147 return 1; 148 } 149 150 ptp_script_msg* dequeue_script_msg(ptp_script_msg_q *q) { 151 ptp_script_msg *msg; 152 if(script_msg_q_empty(q)) { 153 return NULL; 154 } 155 msg = q->q[q->r]; 156 q->r = script_msg_q_next(q->r); 157 return msg; 158 } 159 160 // public interface for script 161 ptp_script_msg* ptp_script_create_msg(unsigned type, unsigned subtype, unsigned datasize, const void *data) { 162 ptp_script_msg *msg; 163 if(!datasize) { 164 return NULL; 165 } 166 msg = malloc(sizeof(ptp_script_msg) + datasize); 167 msg->size = datasize; 168 msg->type = type; 169 msg->subtype = subtype; 170 // caller may fill in data themselves 171 if(data) { 172 memcpy(msg->data,data,msg->size); 173 } 174 return msg; 175 } 176 177 int ptp_script_write_msg(ptp_script_msg *msg) { 178 msg->script_id = script_run_id; 179 return enqueue_script_msg(&msg_q_out,msg); 180 } 181 182 ptp_script_msg* ptp_script_read_msg(void) { 183 ptp_script_msg *msg; 184 while(1) { 185 msg = dequeue_script_msg(&msg_q_in); 186 // no messages 187 if(!msg) { 188 return NULL; 189 } 190 // does message belong to our script 191 if(!msg->script_id || msg->script_id == script_run_id) { 192 return msg; 193 } else { 194 // no: discard and keep looking 195 free(msg); 196 } 197 } 198 } 199 int ptp_script_write_error_msg(unsigned errtype, const char *err) { 200 if(script_msg_q_full(&msg_q_out)) { 201 return 0; 202 } 203 ptp_script_msg *msg = ptp_script_create_msg(PTP_CHDK_S_MSGTYPE_ERR,errtype,strlen(err),err); 204 if(!msg) { 205 return 0; 206 } 207 return ptp_script_write_msg(msg); 208 } 209 210 #endif 211 96 212 static int handle_ptp( 97 213 int h, ptp_data *data, int opcode, int sess_id, int trans_id, … … 100 216 static union { 101 217 char *str; 102 #ifdef OPT_LUA103 lua_State *lua_state;104 #endif105 218 } temp_data; 106 219 static int temp_data_kind = 0; // 0: nothing, 1: ascii string, 2: lua object … … 115 228 ptp.num_param = 0; 116 229 230 // TODO calling this on every PTP command is not good, 231 // since it figures out free memory by repeatedly malloc'ing! 117 232 buf_size=core_get_free_memory()>>1; 118 233 … … 139 254 #ifdef OPT_SCRIPTING 140 255 ptp.param1 |= script_is_running()?PTP_CHDK_SCRIPT_STATUS_RUN:0; 256 ptp.param1 |= (!script_msg_q_empty(&msg_q_out))?PTP_CHDK_SCRIPT_STATUS_MSG:0; 141 257 #endif 142 258 break; … … 210 326 l = temp_data_extra; 211 327 } 212 #ifdef OPT_LUA213 else { // temp_data_kind == 2214 s = lua_tolstring(get_lua_thread(temp_data.lua_state),1,&l);215 }216 #endif217 328 218 329 if ( !send_ptp_data(data,s,l) ) … … 227 338 free(temp_data.str); 228 339 } 229 #ifdef OPT_LUA230 else if ( temp_data_kind == 2 )231 {232 lua_close(temp_data.lua_state);233 }234 #endif235 340 temp_data_kind = 0; 236 341 … … 257 362 free(temp_data.str); 258 363 } 259 #ifdef OPT_LUA260 else if ( temp_data_kind == 2 )261 {262 lua_close(temp_data.lua_state);263 }264 #endif265 364 temp_data_kind = 0; 266 365 } … … 392 491 393 492 #ifdef OPT_LUA 493 // TODO this should flush data even if scripting isn't supported 394 494 case PTP_CHDK_ExecuteScript: 395 495 { 396 496 int s; 397 497 char *buf; 498 499 script_run_id++; 500 ptp.num_param = 2; 501 ptp.param1 = script_run_id; 398 502 399 503 if ( param2 != PTP_CHDK_SL_LUA ) … … 414 518 recv_ptp_data(data,buf,s); 415 519 416 long script_action_stack = script_start_ptp(buf, param3&PTP_CHDK_ES_RESULT); 520 // error details will be passed in a message 521 if (script_start_ptp(buf) < 0) { 522 ptp.param2 = PTP_CHDK_S_ERRTYPE_COMPILE; 523 } else { 524 ptp.param2 = PTP_CHDK_S_ERRTYPE_NONE; 525 } 417 526 418 527 free(buf); 419 528 420 if (script_action_stack < 0) 421 { 422 ptp.code = PTP_RC_InvalidParameter; 423 break; 424 } 425 else 426 { 427 428 if ( param3 & PTP_CHDK_ES_WAIT ) 429 { 430 431 while ( script_is_running() ) 432 msleep(100); 433 434 if ( param3 & PTP_CHDK_ES_RESULT ) 435 { 436 lua_State *Lt; 437 temp_data.lua_state = lua_consume_result(); 438 Lt = get_lua_thread(temp_data.lua_state); 439 temp_data_kind = 2; 440 if ( lua_gettop(Lt) == 0 ) 441 { 442 temp_data_extra = PTP_CHDK_TYPE_NOTHING; 443 } else if ( lua_isnil(Lt,1) ) 444 { 445 temp_data_extra = PTP_CHDK_TYPE_NIL; 446 } else if ( lua_isboolean(Lt,1) ) 447 { 448 temp_data_extra = PTP_CHDK_TYPE_BOOLEAN; 449 } else if ( lua_isnumber(Lt,1) ) 450 { 451 temp_data_extra = PTP_CHDK_TYPE_INTEGER; 452 } else if ( lua_isstring(Lt,1) ) 453 { 454 temp_data_extra = PTP_CHDK_TYPE_STRING; 455 } else if ( lua_istable(Lt,1) ) 456 { 457 temp_data_extra = PTP_CHDK_TYPE_NOTHING; 458 int i; 459 int count = 0; 460 lua_pushstring(Lt,""); 461 lua_pushnil(Lt); 462 while (lua_next(Lt,1) ) 463 { 464 lua_pushvalue(Lt,-2); 465 lua_insert(Lt,-4); 466 if ( lua_istable(Lt,-1) && (lua_objlen(Lt,-1) > 0) ) 467 { 468 lua_pushstring(Lt,""); 469 for ( i = 1; i <= lua_objlen(Lt,-2); i++ ) 470 { 471 lua_rawgeti(Lt,-2,i); 472 if ( lua_isnil(Lt,-1) ) 473 { 474 lua_pushstring(Lt,"nil"); 475 lua_remove(Lt,-2); 476 } 477 if ( lua_isboolean(Lt,-1) ) 478 { 479 lua_pushstring(Lt,lua_toboolean(Lt,-1)?"true":"false"); 480 lua_remove(Lt,-2); 481 } 482 if ( !lua_isstring(Lt,-1) ) 483 { 484 lua_pop(Lt,1); 485 lua_pushstring(Lt,""); 486 } 487 if ( lua_objlen(Lt,-2) > 0 ) 488 { 489 lua_pushlstring(Lt,"\t",1); 490 lua_insert(Lt,-2); 491 lua_concat(Lt,3); 492 } 493 else lua_concat(Lt,2); 494 } 495 lua_remove(Lt,-2); 496 } 497 if ( lua_isboolean(Lt,-1) ) 498 { 499 lua_pushstring(Lt,lua_toboolean(Lt,-1)?"true":"false"); 500 lua_remove(Lt,-2); 501 } 502 if ( lua_isstring(Lt,-1) ) 503 { 504 lua_pushlstring(Lt,"\t",1); 505 lua_insert(Lt,-2); 506 if ( lua_objlen(Lt,-4) > 0 ) 507 { 508 lua_pushlstring(Lt,"\n",1); 509 lua_insert(Lt,-4); 510 lua_concat(Lt, 5); 511 } 512 else lua_concat(Lt, 4); 513 } 514 else lua_pop(Lt,2); 515 lua_insert(Lt,-2); 516 lua_pushvalue(Lt,-1); //set entry to nil for save memory 517 lua_pushnil(Lt); 518 lua_settable(Lt,1); 519 } 520 if ( lua_gettop(Lt) == 2 ) lua_remove(Lt,1); 521 if ( lua_isstring(Lt,1) && ( lua_objlen(Lt,1) > 0 )) temp_data_extra = PTP_CHDK_TYPE_STRING; 522 } else { 523 temp_data_extra = PTP_CHDK_TYPE_NOTHING; 524 } 525 ptp.num_param = 1; 526 ptp.param1 = temp_data_extra; 527 if ( temp_data_extra != PTP_CHDK_TYPE_STRING ) 528 { 529 if ( temp_data_extra == PTP_CHDK_TYPE_BOOLEAN ) 530 { 531 ptp.num_param = 2; 532 ptp.param2 = lua_toboolean(Lt,1); 533 } if ( temp_data_extra == PTP_CHDK_TYPE_INTEGER ) 534 { 535 ptp.num_param = 2; 536 ptp.param2 = lua_tonumber(Lt,1); 537 } 538 lua_close(Lt); 539 temp_data_kind = 0; 540 } else { 541 ptp.num_param = 2; 542 ptp.param2 = lua_objlen(Lt,1); 543 } 544 } 545 } 546 } 547 548 break; 549 } 529 break; 530 } 531 case PTP_CHDK_ReadScriptMsg: 532 { 533 ptp_script_msg *msg = dequeue_script_msg(&msg_q_out); 534 ptp.num_param = 4; 535 if(!msg) { 536 // return a fully formed message for easier handling 537 ptp.param1 = PTP_CHDK_S_MSGTYPE_NONE; 538 ptp.param2 = 0; 539 ptp.param3 = 0; 540 ptp.param4 = 4; 541 // looks like we need to send some data no matter what 542 if ( !send_ptp_data(data,"\0\0\0",4) ) 543 { 544 ptp.code = PTP_RC_GeneralError; 545 } 546 break; 547 } 548 ptp.param1 = msg->type; 549 ptp.param2 = msg->subtype; 550 ptp.param3 = msg->script_id; 551 ptp.param4 = msg->size; 552 553 // NOTE message is lost if sending failed 554 if ( !send_ptp_data(data,msg->data,msg->size) ) 555 { 556 ptp.code = PTP_RC_GeneralError; 557 } 558 free(msg); 559 break; 560 } 561 case PTP_CHDK_WriteScriptMsg: 562 { 563 int msg_size; 564 ptp_script_msg *msg; 565 ptp.num_param = 1; 566 ptp.param1 = PTP_CHDK_S_MSGSTATUS_OK; 567 if (!script_is_running()) { 568 ptp.param1 = PTP_CHDK_S_MSGSTATUS_NOTRUN; 569 } 570 // check if target script for message is running 571 if(param2 && param2 != script_run_id) { 572 ptp.param1 = PTP_CHDK_S_MSGSTATUS_BADID; 573 } 574 if(script_msg_q_full(&msg_q_in)) { 575 ptp.param1 = PTP_CHDK_S_MSGSTATUS_QFULL; 576 } 577 578 msg_size = data->get_data_size(data->handle); 579 580 // if something was wrong, don't bother creating message, just flush 581 if(ptp.param1 != PTP_CHDK_S_MSGSTATUS_OK) { 582 flush_recv_ptp_data(data,msg_size); 583 break; 584 } 585 msg = ptp_script_create_msg(PTP_CHDK_S_MSGTYPE_USER,PTP_CHDK_TYPE_STRING,msg_size,NULL); 586 if ( !msg ) // malloc error or zero size 587 { 588 // if size is zero, things will get hosed no matter what 589 flush_recv_ptp_data(data,msg_size); 590 ptp.code = PTP_RC_GeneralError; 591 break; 592 } 593 msg->script_id = param2; 594 if ( !recv_ptp_data(data,msg->data,msg->size) ) 595 { 596 ptp.code = PTP_RC_GeneralError; 597 free(msg); 598 break; 599 } 600 if( !enqueue_script_msg(&msg_q_in,msg) ) { 601 ptp.code = PTP_RC_GeneralError; 602 free(msg); 603 } 604 break; 605 } 550 606 #endif 551 607 -
branches/reyalp-ptp/core/ptp.h
r1051 r1083 1 1 #ifndef __PTP_H 2 2 #define __PTP_H 3 4 // N.B.: not checking to see if CAM_CHDK_PTP is set as ptp.h is currently 5 // only included by ptp.c (which already checks this before including ptp.h) 6 7 #define PTP_CHDK_VERSION_MAJOR 0 // increase only with backwards incompatible changes (and reset minor) 8 #define PTP_CHDK_VERSION_MINOR 2 // increase with extensions of functionality 3 #define PTP_CHDK_VERSION_MAJOR 1 // increase only with backwards incompatible changes (and reset minor) 4 #define PTP_CHDK_VERSION_MINOR 0 // increase with extensions of functionality 9 5 /* 10 6 protocol version history 11 7 0.1 - initial proposal from mweerden, + luar 12 8 0.2 - Added ScriptStatus and ScriptSupport, based on work by ultimA 9 1.0 - removed old script result code (luar), replace with message system 13 10 */ 14 11 … … 39 36 PTP_CHDK_ExecuteScript, // data is script to be executed 40 37 // param2 is language of script 41 // param3 is for the ES flags below 42 PTP_CHDK_ScriptStatus, // Script execution status 43 // param1 CHDK_PTP_SCRIPT_STATUS_RUN is set if a script running, cleared if not 44 // all other bits and params are reserved for future use 38 // return param1 is script id, like a process id 39 // return param2 is status, PTP_CHDK_S_ERRTYPE* 40 PTP_CHDK_ScriptStatus, // Script execution status 41 // return param1 bits 42 // CHDK_PTP_SCRIPT_STATUS_RUN is set if a script running, cleared if not 43 // CHDK_PTP_SCRIPT_STATUS_MSG is set if script messages from script waiting to be read 44 // all other bits and params are reserved for future use 45 45 PTP_CHDK_ScriptSupport, // Which scripting interfaces are supported in this build 46 46 // param1 CHDK_PTP_SUPPORT_LUA is set if lua is supported, cleared if not 47 // all other bits and params are reserved for future use 47 // all other bits and params are reserved for future use 48 PTP_CHDK_ReadScriptMsg, // read next message from camera script system 49 // return param1 is message type: none, script error, script return, user, TODO chdk console data 50 // return param2 is message subtype: for script return and users this is chdk_ptp_type, for error it may be an error code (TBD) 51 // return param3 is script id of script that generated the message 52 // return param4 is length of the message data 53 // return data is message. 54 // A minum of 4 bytes of zeros is returned if there would not be data otherwise 55 PTP_CHDK_WriteScriptMsg, // write a message for scripts running on camera 56 // input param2 is target script id, 0=don't care. Messages for a non-running script will be discarded 57 // data length is handled by ptp data phase 58 // input messages do not have type or subtype, they are always a string destined for the script (similar to USER/string) 59 // output param1 is status (OK,queue full,wrong script,script not running) 48 60 } ptp_chdk_command; 49 61 50 // data types as used by TempData and ExecuteScript62 // data types as used by ReadScriptMessage 51 63 enum { 52 PTP_CHDK_TYPE_ NOTHING = 0,64 PTP_CHDK_TYPE_UNSUPPORTED = 0, // type name will be returned in data 53 65 PTP_CHDK_TYPE_NIL, 54 66 PTP_CHDK_TYPE_BOOLEAN, 55 67 PTP_CHDK_TYPE_INTEGER, 56 PTP_CHDK_TYPE_STRING 68 PTP_CHDK_TYPE_STRING, // NOTE tables currently returned as string 57 69 } ptp_chdk_type; 58 70 … … 64 76 // just clear 65 77 66 // ExecuteScript flags 67 #define PTP_CHDK_ES_WAIT 0x1 // do not return after script initialisation 68 // but wait until execution has finished 69 // (should only be used with short execution 70 // times) 71 #define PTP_CHDK_ES_RESULT 0x2 // only in combination with WAIT; return 72 // param1 will be the ptp_chdk_type of the 73 // code result and param2 the value (booleans 74 // and integers) or length (strings) 75 76 // Script Languages - for execution 78 // Script Languages - for execution only lua is supported for now 77 79 #define PTP_CHDK_SL_LUA 0 78 80 #define PTP_CHDK_SL_UBASIC 1 79 81 80 82 // bit flags for script status 81 #define PTP_CHDK_SCRIPT_STATUS_RUN 0x1 83 #define PTP_CHDK_SCRIPT_STATUS_RUN 0x1 // script running 84 #define PTP_CHDK_SCRIPT_STATUS_MSG 0x2 // messages waiting 82 85 // bit flags for scripting support 83 86 #define PTP_CHDK_SCRIPT_SUPPORT_LUA 0x1 84 87 88 // message types 89 #define PTP_CHDK_S_MSGTYPE_NONE 0 // no messages waiting 90 #define PTP_CHDK_S_MSGTYPE_ERR 1 // error message 91 #define PTP_CHDK_S_MSGTYPE_RET 2 // script return value 92 #define PTP_CHDK_S_MSGTYPE_USER 3 // message queued by script 93 94 // error subtypes for PTP_CHDK_S_MSGTYPE_ERR and script startup status 95 #define PTP_CHDK_S_ERRTYPE_NONE 0 96 #define PTP_CHDK_S_ERRTYPE_COMPILE 1 97 #define PTP_CHDK_S_ERRTYPE_RUN 2 98 99 // message status 100 #define PTP_CHDK_S_MSGSTATUS_OK 0 // queued ok 101 #define PTP_CHDK_S_MSGSTATUS_NOTRUN 1 // no script is running 102 #define PTP_CHDK_S_MSGSTATUS_QFULL 2 // queue is full 103 #define PTP_CHDK_S_MSGSTATUS_BADID 3 // specified ID is not running 85 104 #endif // __PTP_H -
branches/reyalp-ptp/core/script.c
r1051 r1083 467 467 } 468 468 469 static voidwait_and_end(void)469 void script_wait_and_end(void) 470 470 { 471 471 script_console_add_line("PRESS SHUTTER TO CLOSE"); … … 496 496 497 497 if (Lres != LUA_YIELD && Lres != 0) { 498 script_console_add_line( lua_tostring( Lt, -1 ) ); 499 if(conf.debug_lua_restart_on_error){ 500 lua_script_reset(); 501 script_start_gui(0); 502 } else { 503 wait_and_end(); 504 } 498 lua_script_error(Lt,1); 505 499 return; 506 500 } 507 501 508 502 if (Lres != LUA_YIELD) { 503 // add ptp result 504 lua_script_finish(Lt); 509 505 script_console_add_line(lang_str(LANG_CONSOLE_TEXT_FINISHED)); 510 506 action_pop(); … … 556 552 } 557 553 break; 554 #if defined(OPT_LUA) && defined(CAM_CHDK_PTP) 555 case AS_SCRIPT_READ_USB_MSG: 556 if(L) { // only lua supported for now 557 ptp_script_msg *msg = ptp_script_read_msg(); 558 if(action_process_delay(2) || msg) { 559 if(msg) { 560 lua_pushlstring( Lt,msg->data,msg->size); 561 } else { 562 lua_pushnil(Lt); 563 } 564 action_clear_delay(); 565 action_pop(); 566 action_pop(); 567 } 568 } 569 break; 570 case AS_SCRIPT_WRITE_USB_MSG: 571 if(L) { // only lua supported for now 572 ptp_script_msg *msg = (ptp_script_msg *)action_get_prev(2); 573 int r = ptp_script_write_msg(msg); 574 if(action_process_delay(3) || r) { 575 action_clear_delay(); 576 action_pop(); 577 action_pop(); 578 action_pop(); 579 lua_pushboolean(Lt,r); 580 } 581 } 582 break; 583 #endif 558 584 default: 559 585 if (!action_stack_standard(p) && !state_kbd_script_run) … … 630 656 if( is_lua() ) { 631 657 #ifdef OPT_LUA 632 if( !lua_script_start(script_source_str) ) { 633 script_print_screen_end(); 634 wait_and_end(); 658 if( !lua_script_start(script_source_str,0) ) { 635 659 return -1; 636 660 } … … 673 697 } 674 698 675 #ifdef OPT_LUA 676 long script_start_ptp( char *script , int keep_result ) 677 { 678 if (!lua_script_start(script)) return -1; 679 lua_keep_result = keep_result; 699 #if defined(OPT_LUA) && defined(CAM_CHDK_PTP) 700 long script_start_ptp( char *script ) 701 { 702 if (!lua_script_start(script,1)) return -1; 680 703 state_lua_kbd_first_call_to_resume = 1; 681 704 state_kbd_script_run = 1; -
branches/reyalp-ptp/include/platform.h
r1024 r1083 541 541 void init_chdk_ptp_task(); 542 542 543 typedef struct { 544 unsigned size; 545 unsigned script_id; // id of script message is to/from 546 unsigned type; 547 unsigned subtype; 548 char data[]; 549 } ptp_script_msg; 550 int ptp_script_write_msg(ptp_script_msg *msg); 551 ptp_script_msg* ptp_script_read_msg(void); 552 ptp_script_msg* ptp_script_create_msg(unsigned type, unsigned subtype, unsigned datasize, const void *data); 553 int ptp_script_write_error_msg(unsigned errtype, const char *err); 554 543 555 #endif // CAM_CHDK_PTP 544 556 -
branches/reyalp-ptp/include/script.h
r1036 r1083 32 32 //------------------------------------------------------------------- 33 33 34 extern long script_start_ptp(char *script, int keep_result);35 34 long script_stack_start(); 36 35 int script_is_running(); … … 42 41 int script_keyid_by_name( const char *name ); 43 42 #ifdef OPT_LUA 44 long script_start_ptp( char *script , int keep_result);43 long script_start_ptp( char *script ); 45 44 #endif 45 void script_wait_and_end(); 46 46 47 47 #endif
Note: See TracChangeset
for help on using the changeset viewer.