extern void finalize_store_wrapper (struct dt_imageio_module_storage_t *self, dt_imageio_module_data_t *data) { lua_State *L =darktable.lua_state; lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_getfield(L,-1,self->plugin_name); lua_getfield(L,-1,"finalize_store"); if(lua_isnil(L,-1)) { lua_pop(L,3); return; } luaA_push_typeid(L,self->parameter_lua_type,&data); lua_storage_t *d = (lua_storage_t*) data; GList* imgids =d->imgids; GList* file_names = d->file_names; lua_newtable(L); while(imgids) { luaA_push(L,dt_lua_image_t,&(imgids->data)); lua_pushstring(L,file_names->data); lua_settable(L,-3); imgids = g_list_next(imgids); file_names = g_list_next(file_names); } lua_pushlightuserdata(L,data); lua_gettable(L,LUA_REGISTRYINDEX); dt_lua_do_chunk(L,3,0); lua_pop(L,2); }
static int trigger_keyed_event(lua_State * L) { int nargs = luaL_checknumber(L,-1); const char* evt_name = luaL_checkstring(L,-2); lua_pop(L,2); // -1..-n are our args const int top_marker=lua_gettop(L); lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_event_data"); lua_getfield(L,-1,evt_name); if(lua_isnil(L,-1)) { lua_pop(L,2+nargs); return 0; } const char*key=luaL_checkstring(L,-nargs-2); // first arg is the key itself lua_getfield(L,-1,key); if(lua_isnil(L,-1)) { lua_pop(L,2+nargs); return 0; } // prepare the call lua_insert(L,top_marker-nargs+1); lua_pushstring(L,evt_name);// param 1 is the event lua_insert(L,top_marker-nargs+2); lua_pop(L,2); return dt_lua_do_chunk(L,nargs+1,0); }
static int trigger_multiinstance_event(lua_State * L) { int nargs = luaL_checknumber(L,-1); const char* evt_name = luaL_checkstring(L,-2); lua_pop(L,2); // -1..-n are our args const int top_marker=lua_gettop(L); lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_event_data"); lua_getfield(L,-1,evt_name); if(lua_isnil(L,-1)) { lua_pop(L,2+nargs); return 0; } lua_remove(L,-2); lua_pushnil(L); /* first key */ int nresult = 0; while (lua_next(L, top_marker +1) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) value is the function to call*/ // prepare the call lua_pushstring(L,evt_name);// param 1 is the event for(int i = 0 ; i<nargs ;i++) { // event dependant parameters lua_pushvalue(L, top_marker -nargs +1 +i); } nresult += dt_lua_do_chunk(L,nargs+1,0); } return nresult; }
static int trigger_multiinstance_event(lua_State * L,const char* evt_name, int nargs,int nresults) { // -1..-n are our args const int top_marker=lua_gettop(L); lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_event_data"); lua_getfield(L,-1,evt_name); if(lua_isnil(L,-1)) { lua_pop(L,2+nargs); if(nresults == LUA_MULTRET) return 0; for(int i = 0 ; i < nresults ; i++) lua_pushnil(L); return nresults; } lua_remove(L,-2); lua_pushnil(L); /* first key */ int result = 0; while (lua_next(L, top_marker +1) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) value is the function to call*/ // prepare the call lua_pushstring(L,evt_name);// param 1 is the event for(int i = 0 ; i<nargs ;i++) { // event dependant parameters lua_pushvalue(L, top_marker -nargs +1 +i); } int tmp_result = dt_lua_do_chunk(L,nargs+1,nresults); if(tmp_result > 0) { lua_pushvalue(L,-(tmp_result+1));//push index on top lua_remove(L,-(tmp_result+2));//remove old index still in stack } result += tmp_result; } return result; }
static int trigger_keyed_event(lua_State * L,const char* evt_name, int nargs,int nresults) { // -1..-n are our args const int top_marker=lua_gettop(L); lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_event_data"); lua_getfield(L,-1,evt_name); if(lua_isnil(L,-1)) { lua_pop(L,2+nargs); if(nresults == LUA_MULTRET) return 0; for(int i = 0 ; i < nresults ; i++) lua_pushnil(L); return nresults; } const char*key=luaL_checkstring(L,-nargs-2); // first arg is the key itself lua_getfield(L,-1,key); if(lua_isnil(L,-1)) { lua_pop(L,2+nargs); if(nresults == LUA_MULTRET) return 0; for(int i = 0 ; i < nresults ; i++) lua_pushnil(L); return nresults; } // prepare the call lua_insert(L,top_marker-nargs+1); lua_pushstring(L,evt_name);// param 1 is the event lua_insert(L,top_marker-nargs+2); lua_pop(L,2); return dt_lua_do_chunk(L,nargs+1,nresults); }
gboolean dt_lua_gtk_wrap_callback(gpointer data) { gtk_wrap_communication *communication = (gtk_wrap_communication*)data; g_mutex_lock(&communication->end_mutex); communication->retval = dt_lua_do_chunk(communication->L,lua_gettop(communication->L)-1,LUA_MULTRET); g_cond_signal(&communication->end_cond); g_mutex_unlock(&communication->end_mutex); return false; }
int dt_lua_dostring(lua_State *L,const char* command) { if(luaL_loadstring(L, command)) { dt_print(DT_DEBUG_LUA,"LUA ERROR %s\n",lua_tostring(L,-1)); lua_pop(L,1); return -1; } return dt_lua_do_chunk(L,0,0); }
int dt_lua_dofile(lua_State *L,const char* filename) { if(luaL_loadfile(L, filename)) { dt_print(DT_DEBUG_LUA,"LUA ERROR %s\n",lua_tostring(L,-1)); lua_pop(L,1); return -1; } return dt_lua_do_chunk(L,0,0); }
static int store_wrapper(struct dt_imageio_module_storage_t *self,struct dt_imageio_module_data_t *self_data, const int imgid, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, const int num, const int total, const gboolean high_quality) { /* construct a temporary file name */ char tmpdir[DT_MAX_PATH_LEN]= {0}; gboolean from_cache = FALSE; dt_loc_get_tmp_dir (tmpdir,DT_MAX_PATH_LEN); char dirname[DT_MAX_PATH_LEN]; dt_image_full_path(imgid, dirname, DT_MAX_PATH_LEN, &from_cache); const gchar * filename = g_path_get_basename( dirname ); gchar * end = g_strrstr( filename,".")+1; g_strlcpy( end, format->extension(fdata), sizeof(dirname)-(end-dirname)); gchar* complete_name = g_build_filename( tmpdir, filename, (char *)NULL ); if(dt_imageio_export(imgid, complete_name, format, fdata, high_quality) != 0) { fprintf(stderr, "[%s] could not export to file: `%s'!\n", self->name(self),complete_name); g_free(complete_name); return 1; } lua_storage_t *d = (lua_storage_t*) self_data; d->imgids = g_list_prepend(d->imgids,(void*)(intptr_t)imgid); d->file_names = g_list_prepend(d->file_names,complete_name); lua_State *L =darktable.lua_state; lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_getfield(L,-1,self->plugin_name); lua_getfield(L,-1,"store"); if(lua_isnil(L,-1)) { lua_pop(L,3); return 1; } luaA_push_typeid(L,self->parameter_lua_type,self_data); luaA_push(L,dt_lua_image_t,&imgid); luaA_push_typeid(L,format->parameter_lua_type,fdata); lua_pushstring(L,complete_name); lua_pushnumber(L,num); lua_pushnumber(L,total); lua_pushboolean(L,high_quality); lua_pushlightuserdata(L,self_data); lua_gettable(L,LUA_REGISTRYINDEX); dt_lua_do_chunk(L,8,1); int result = lua_toboolean(L,-1); lua_pop(L,2); return result; }
int dt_lua_dostring(lua_State *L, const char *command, int nargs, int nresults) { int load_result = luaL_loadstring(L, command); if(load_result != LUA_OK) { const char *error_msg = lua_tostring(L, -1); luaL_traceback(L, L, error_msg, 0); lua_remove(L, -2); return load_result; } lua_insert(L, -(nargs + 1)); return dt_lua_do_chunk(L, nargs, nresults); }
static int trigger_chained_event(lua_State * L,const char* evt_name, int nargs,int nresults) { // -1..-n a if(nargs<nresults) dt_print(DT_DEBUG_LUA,"error chained parameters must have less results than args (args %d results %d\n",nargs,nresults); int arg_top=lua_gettop(L); lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_event_data"); lua_getfield(L,-1,evt_name); if(lua_isnil(L,-1)) { lua_pop(L,2); // remove what we built for(int i = 0 ; i < nargs - nresults ; i++) lua_remove(L,-(nresults+1)); return nresults; } lua_remove(L,-2); // copy variable args on the top of the stack for(int i = 0 ; i< nresults; i++) { lua_pushvalue(L,arg_top -nresults +i+1); } lua_pushnil(L); /* first key */ while (lua_next(L, -(nresults+2)) != 0) { /* stack at this point - all args from the function entry - table with all the functions to chain - variable args at this point - "key" the index we just looked into - "value" function to call */ // remove the loop index const int loop_index=luaL_checkint(L,-2); lua_remove(L,-2); // move the function below the variable args lua_insert(L,-(nresults+1)); // move fn call below args //move the evt name just above the function lua_pushstring(L,evt_name);// param 1 is the event lua_insert(L,-(nresults+1)); // move evt name below params // add all fixed args at their final place for(int i = 0; i < nargs - nresults ; i++) { lua_pushvalue(L,arg_top -nargs+i+1); // copy all invariant args at the top lua_insert(L,-(nresults+1));// move them at their final place } /* uses 'key' (at index -2) and 'value' (at index -1) */ // prepare the call dt_lua_do_chunk(L,nargs+1,nresults); lua_pushinteger(L,loop_index); } for(int i=0; i< nargs+1 ; i++) lua_remove(L,-nresults -1); //remove all args that are below the results and the fn table return nresults; }
int dt_lua_do_chunk_raise(lua_State *L, int nargs, int nresults) { int orig_top = lua_gettop(L); int thread_result = dt_lua_do_chunk(L, nargs, nresults); if(thread_result == LUA_OK) { return lua_gettop(L) - (orig_top -nargs -1); } else { const char *message = lua_tostring(L, -1); return luaL_error(L, message); } }
static int32_t lua_job_canceled_job(dt_job_t *job) { dt_progress_t *progress = dt_control_job_get_params(job); lua_State * L = darktable.lua_state.state; gboolean has_lock = dt_lua_lock(); luaA_push(L, dt_lua_backgroundjob_t, &progress); lua_getuservalue(L, -1); lua_getfield(L, -1, "cancel_callback"); lua_pushvalue(L, -3); dt_lua_do_chunk(L, 1, 0); lua_pop(L, 2); dt_lua_unlock(has_lock); return 0; }
static gboolean poll_events(gpointer data) { int my_id = GPOINTER_TO_INT(data); lua_getfield(darktable.lua_state,LUA_REGISTRYINDEX,"dt_lua_delayed_events"); lua_rawgeti(darktable.lua_state,-1,my_id); if(lua_isnoneornil(darktable.lua_state,-1)) { lua_pop(darktable.lua_state,2); luaL_error(darktable.lua_state,"Unknown thread was called for delay action"); return FALSE; } lua_State * L = lua_tothread(darktable.lua_state,-1); dt_lua_do_chunk(L,lua_gettop(L) -1,0); /* L is finished, remove it from the stack */ luaL_unref(darktable.lua_state,-2,my_id); lua_pop(darktable.lua_state,2); return FALSE; }
static void run_event(const char*event,int nargs) { lua_getfield(darktable.lua_state.state,LUA_REGISTRYINDEX,"dt_lua_event_list"); if(lua_isnil(darktable.lua_state.state,-1)) {// events have been disabled lua_settop(darktable.lua_state.state,0); return; } lua_getfield(darktable.lua_state.state,-1,event); event_handler * handler = lua_touserdata(darktable.lua_state.state,-1); lua_pop(darktable.lua_state.state,2); if(!handler->in_use) { lua_pop(darktable.lua_state.state,nargs); return; } lua_pushcfunction(darktable.lua_state.state,handler->on_event); lua_insert(darktable.lua_state.state,-nargs -1); lua_pushstring(darktable.lua_state.state,event); lua_pushnumber(darktable.lua_state.state,nargs); dt_lua_do_chunk(darktable.lua_state.state,nargs+2,0); }
void dt_lua_widget_trigger_callback_glist(lua_State*L,lua_widget object,const char* name,GList*extra) { luaA_push_type(L,object->type->associated_type,&object); lua_getuservalue(L,-1); lua_getfield(L,-1,name); if(! lua_isnil(L,-1)) { lua_pushvalue(L,-3); GList* cur_elt = extra; int nargs = 1; while(cur_elt) { const char* next_type = cur_elt->data; cur_elt = g_list_next(cur_elt); luaA_push_type(L,luaA_type_find(L,next_type),&cur_elt->data); nargs++; cur_elt = g_list_next(cur_elt); } dt_lua_do_chunk(L,nargs,0); } dt_lua_redraw_screen(); g_list_free(extra); lua_pop(L,2); }
static int default_supported_wrapper (struct dt_imageio_module_storage_t *self, struct dt_imageio_module_format_t *format) { lua_State *L =darktable.lua_state; lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_getfield(L,-1,self->plugin_name); lua_getfield(L,-1,"supported"); if(lua_isnil(L,-1)) { lua_pop(L,3); return true; } dt_imageio_module_data_t *sdata = self->get_params(self); dt_imageio_module_data_t *fdata = format->get_params(format); luaA_push_typeid(L,self->parameter_lua_type,sdata); luaA_push_typeid(L,format->parameter_lua_type,fdata); format->free_params(format,fdata); self->free_params(self,sdata); dt_lua_do_chunk(L,2,1); int result = lua_toboolean(L,-1); lua_pop(L,2); return result; };
int dt_lua_do_chunk_silent(lua_State *L, int nargs, int nresults) { int orig_top = lua_gettop(L); int thread_result = dt_lua_do_chunk(L, nargs, nresults); if(thread_result == LUA_OK) { return lua_gettop(L) - (orig_top -nargs -1); } if(darktable.unmuted & DT_DEBUG_LUA) { dt_print(DT_DEBUG_LUA, "LUA ERROR : %s", lua_tostring(L, -1)); } lua_pop(L, 1); // remove the error message if(nresults != LUA_MULTRET) { for(int i = 0; i < nresults; i++) { lua_pushnil(L); } return nresults; } return 0; }
static int register_storage(lua_State *L) { lua_settop(L,5); lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_newtable(L); dt_imageio_module_storage_t * storage = malloc(sizeof(dt_imageio_module_storage_t)); memcpy(storage,&ref_storage,sizeof(dt_imageio_module_storage_t)); storage->gui_data = malloc(sizeof(lua_storage_gui_t)); lua_storage_gui_t * data = storage->gui_data; const char * plugin_name = luaL_checkstring(L,1); lua_pushvalue(L,1); lua_setfield(L,-2,"plugin_name"); g_strlcpy(storage->plugin_name,plugin_name,sizeof(storage->plugin_name)); const char * name = luaL_checkstring(L,2); lua_pushvalue(L,2); lua_setfield(L,-2,"name"); data->name = strdup(name); data->supported_formats = NULL; if(!lua_isnoneornil(L,3)) { luaL_checktype(L,3,LUA_TFUNCTION); lua_pushvalue(L,3); lua_setfield(L,-2,"store"); } if(lua_isnil(L,4) ) { storage->finalize_store = NULL; } else { luaL_checktype(L,4,LUA_TFUNCTION); lua_pushvalue(L,4); lua_setfield(L,-2,"finalize_store"); } if(!lua_isnoneornil(L,5)) { luaL_checktype(L,5,LUA_TFUNCTION); lua_pushvalue(L,5); lua_setfield(L,-2,"supported"); } lua_setfield(L,-2,plugin_name); char tmp[1024]; snprintf(tmp,1024,"dt_imageio_module_data_pseudo_%s",storage->plugin_name); luaA_Type type_id = luaA_type_add(tmp,storage->params_size(storage)); storage->parameter_lua_type = dt_lua_init_type_typeid(darktable.lua_state.state,type_id); luaA_struct_typeid(darktable.lua_state.state,type_id); dt_lua_register_storage_typeid(darktable.lua_state.state,storage,type_id); GList *it = darktable.imageio->plugins_format; if(!lua_isnoneornil(L,5)) { while(it) { lua_pushvalue(L,5); dt_imageio_module_format_t *format = (dt_imageio_module_format_t *)it->data; dt_imageio_module_data_t *sdata = storage->get_params(storage); dt_imageio_module_data_t *fdata = format->get_params(format); luaA_push_typeid(L,storage->parameter_lua_type,sdata); luaA_push_typeid(L,format->parameter_lua_type,fdata); format->free_params(format,fdata); storage->free_params(storage,sdata); dt_lua_do_chunk(L,2,1); int result = lua_toboolean(L,-1); lua_pop(L,1); if(result) { data->supported_formats = g_list_prepend(data->supported_formats,format); } it = g_list_next(it); } } else { // all formats are supported while(it) { dt_imageio_module_format_t *format = (dt_imageio_module_format_t *)it->data; data->supported_formats = g_list_prepend(data->supported_formats,format); it = g_list_next(it); } } dt_imageio_insert_storage(storage); return 0; }
int dt_lua_protect_call(lua_State *L,lua_CFunction func) { lua_pushcfunction(L,func); return dt_lua_do_chunk(L,0,0); }