static int import_images(lua_State *L) { char *full_name = g_realpath(luaL_checkstring(L, -1)); int result; if(!full_name || !g_file_test(full_name, G_FILE_TEST_EXISTS)) { g_free(full_name); return luaL_error(L, "no such file or directory"); } else if(g_file_test(full_name, G_FILE_TEST_IS_DIR)) { result = dt_film_import(full_name); if(result == 0) { g_free(full_name); return luaL_error(L, "error while importing"); } luaA_push(L, dt_lua_film_t, &result); } else { dt_film_t new_film; dt_film_init(&new_film); char *dirname = g_path_get_dirname(full_name); char *expanded_path = dt_util_fix_path(dirname); g_free(dirname); char *final_path = g_realpath(expanded_path); g_free(expanded_path); if(!final_path) { g_free(full_name); return luaL_error(L, "Error while importing : %s\n", strerror(errno)); } result = dt_film_new(&new_film, final_path); free(final_path); if(result == 0) { if(dt_film_is_empty(new_film.id)) dt_film_remove(new_film.id); dt_film_cleanup(&new_film); g_free(full_name); return luaL_error(L, "error while importing"); } result = dt_image_import(new_film.id, full_name, TRUE); if(dt_film_is_empty(new_film.id)) dt_film_remove(new_film.id); dt_film_cleanup(&new_film); if(result == 0) { g_free(full_name); return luaL_error(L, "error while importing"); } luaA_push(L, dt_lua_image_t, &result); } g_free(full_name); return 1; }
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); }
///////////////////////// // toplevel and common ///////////////////////// static int style_table_index(lua_State *L) { int index = luaL_checkinteger(L, -1); if(index < 1) { return luaL_error(L, "incorrect index in database"); } sqlite3_stmt *stmt = NULL; char query[1024]; snprintf(query, sizeof(query), "SELECT name FROM data.styles ORDER BY name LIMIT 1 OFFSET %d", index - 1); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL); if(sqlite3_step(stmt) == SQLITE_ROW) { const char *name = (const char *)sqlite3_column_text(stmt, 0); dt_style_t *style = dt_styles_get_by_name(name); luaA_push(L, dt_style_t, style); free(style); } else { lua_pushnil(L); } sqlite3_finalize(stmt); return 1; }
static int container_member(lua_State*L) { dt_lib_module_t * module = *(dt_lib_module_t**)lua_touserdata(L,1); dt_ui_container_t container; container = module->container(); luaA_push(L,dt_ui_container_t,&container); return 1; }
static int lua_update_metadata(lua_State*L) { dt_lib_module_t *self = lua_touserdata(L, 1); int32_t imgid = lua_tointeger(L,2); dt_lua_module_entry_push(L,"lib",self->plugin_name); lua_getuservalue(L,-1); lua_getfield(L,4,"callbacks"); lua_getfield(L,4,"values"); lua_pushnil(L); while(lua_next(L, 5) != 0) { lua_pushvalue(L,-1); luaA_push(L,dt_lua_image_t,&imgid); lua_call(L,1,1); lua_pushvalue(L,7); lua_pushvalue(L,9); lua_settable(L,6); lua_pop(L, 2); } lua_pushcfunction(L,lua_update_widgets); dt_lua_gtk_wrap(L); lua_pushlightuserdata(L,self); lua_call(L,1,0); return 0; }
static int lua_create_job(lua_State *L) { const char * message = luaL_checkstring(L, 1); gboolean has_progress_bar = lua_toboolean(L, 2); int cancellable = FALSE; if(!lua_isnoneornil(L,3)) { luaL_checktype(L, 3, LUA_TFUNCTION); cancellable = TRUE; } dt_lua_unlock(false); dt_progress_t *progress = dt_control_progress_create(darktable.control, has_progress_bar, message); if(cancellable) { dt_control_progress_make_cancellable(darktable.control, progress, lua_job_cancelled, progress); } dt_lua_lock(); luaA_push(L, dt_lua_backgroundjob_t, &progress); if(cancellable) { lua_getuservalue(L, -1); lua_pushvalue(L, 3); lua_setfield(L, -2, "cancel_callback"); lua_pop(L, 1); } return 1; }
static int selection_cb(lua_State *L) { GList *image = dt_collection_get_selected(darktable.collection, -1); if(lua_gettop(L) > 0) { GList * new_selection = NULL; luaL_checktype(L,-1,LUA_TTABLE); lua_pushnil(L); while (lua_next(L, -2) != 0) { /* uses 'key' (at index -2) and 'value' (at index -1) */ int imgid; luaA_to(L,dt_lua_image_t,&imgid,-1); new_selection = g_list_prepend(new_selection,GINT_TO_POINTER(imgid)); lua_pop(L,1); } new_selection = g_list_reverse(new_selection); dt_lua_unlock(true);// we need the gdk lock to update ui information dt_selection_clear(darktable.selection); dt_selection_select_list(darktable.selection,new_selection); dt_lua_lock(); g_list_free(new_selection); } lua_newtable(L); while(image) { luaA_push(L,dt_lua_image_t,&image->data); luaL_ref(L,-2); image = g_list_delete_link(image, image); } return 1; }
static int film_member(lua_State *L) { const dt_image_t *my_image = checkreadimage(L, 1); luaA_push(L, dt_lua_film_t, &my_image->film_id); releasereadimage(L, my_image); return 1; }
static int group_leader_member(lua_State *L) { const dt_image_t *my_image = checkreadimage(L, 1); luaA_push(L, dt_lua_image_t, &(my_image->group_id)); releasereadimage(L, my_image); return 1; }
static int tag_index(lua_State *L) { dt_lua_tag_t tagid; luaA_to(L, dt_lua_tag_t, &tagid, -2); int index = luaL_checkinteger(L, -1); if(index < 1) { return luaL_error(L, "incorrect index in database"); } sqlite3_stmt *stmt = NULL; char query[1024]; snprintf(query, sizeof(query), "SELECT imgid FROM main.tagged_images WHERE tagid=?1 ORDER BY imgid LIMIT 1 OFFSET %d", index - 1); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, tagid); if(sqlite3_step(stmt) == SQLITE_ROW) { int imgid = sqlite3_column_int(stmt, 0); luaA_push(L, dt_lua_image_t, &imgid); } else { sqlite3_finalize(stmt); luaL_error(L, "incorrect index in database"); } sqlite3_finalize(stmt); return 1; }
static int film_getnum(lua_State*L) { int index = luaL_checkinteger(L,-1); if(index < 1) { return luaL_error(L,"incorrect index in database"); } dt_lua_film_t film_id; luaA_to(L,dt_lua_film_t,&film_id,-2); sqlite3_stmt *stmt = NULL; char query[1024]; snprintf(query,sizeof(query),"select id from images where film_id = ?1 order by id limit 1 offset %d",index -1); DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db),query, -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, film_id); if(sqlite3_step(stmt) == SQLITE_ROW) { dt_lua_image_t imgid = sqlite3_column_int(stmt, 0); luaA_push(L,dt_lua_image_t,&imgid); sqlite3_finalize(stmt); } else { sqlite3_finalize(stmt); return luaL_error(L,"incorrect index in database"); } return 1; }
int dt_lua_duplicate_image(lua_State *L) { int imgid; luaA_to(L, dt_lua_image_t, &imgid, -1); imgid = dt_image_duplicate(imgid); luaA_push(L, dt_lua_image_t, &imgid); return 1; }
static int import_images(lua_State *L) { char* full_name= realpath(luaL_checkstring(L,-1), NULL); int result; if (!g_file_test(full_name, G_FILE_TEST_EXISTS)) { free(full_name); return luaL_error(L,"no such file or directory"); } else if (g_file_test(full_name, G_FILE_TEST_IS_DIR)) { result =dt_film_import(full_name); if(result == 0) { free(full_name); return luaL_error(L,"error while importing"); } luaA_push(L,dt_lua_film_t,&result); } else { dt_film_t new_film; dt_film_init(&new_film); char* dirname =g_path_get_dirname(full_name); result = dt_film_new(&new_film,dirname); if(result == 0) { free(full_name); dt_film_cleanup(&new_film); free(dirname); return luaL_error(L,"error while importing"); } result =dt_image_import(new_film.id,full_name,TRUE); free(dirname); dt_film_cleanup(&new_film); if(result == 0) { free(full_name); return luaL_error(L,"error while importing"); } luaA_push(L,dt_lua_image_t,&result); } free(full_name); return 1; }
static void on_export_image_tmpfile(gpointer instance, int imgid, char *filename, gpointer user_data){ luaA_push(darktable.lua_state,dt_lua_image_t,&imgid); lua_pushstring(darktable.lua_state,filename); dt_lua_trigger_event("intermediate-export-image",2,0); }
static int32_t on_image_imported_callback_job(dt_job_t *job) { gboolean has_lock = dt_lua_lock(); on_image_imported_callback_data_t *t = dt_control_job_get_params(job); luaA_push(darktable.lua_state.state,dt_lua_image_t,&t->imgid); dt_lua_event_trigger(darktable.lua_state.state,"post-import-image",1); free(t); // i am not sure if the free() may happen before the dt_lua_event_trigger as a pointer to the imgid inside of it is pushed to the lua stack dt_lua_unlock(has_lock); return 0; }
static void on_export_image_tmpfile(gpointer instance, int imgid, char *filename, gpointer user_data){ gboolean has_lock = dt_lua_lock(); luaA_push(darktable.lua_state.state,dt_lua_image_t,&imgid); lua_pushstring(darktable.lua_state.state,filename); run_event("intermediate-export-image",2); dt_lua_unlock(has_lock); }
static int hovered_cb(lua_State *L) { int32_t mouse_over_id = dt_control_get_mouse_over_id(); if(mouse_over_id ==-1) { lua_pushnil(L); } else { luaA_push(L,dt_lua_image_t,&mouse_over_id); } return 1; }
static int tag_lib_create(lua_State *L) { const char * name = luaL_checkstring(L,1); dt_lua_tag_t tagid; if(!dt_tag_new_from_gui(name,&tagid)) { return luaL_error(L,"error creating tag %s\n",name); } luaA_push(L,dt_lua_tag_t,&tagid); return 1; }
static void initialize_store_wrapper (struct dt_imageio_module_storage_t *self, dt_imageio_module_data_t *data, dt_imageio_module_format_t *format, dt_imageio_module_data_t *fdata, GList **images, const gboolean high_quality) { gboolean has_lock = dt_lua_lock(); lua_State *L =darktable.lua_state.state; lua_getfield(L,LUA_REGISTRYINDEX,"dt_lua_storages"); lua_getfield(L,-1,self->plugin_name); lua_getfield(L,-1,"initialize_store"); if(lua_isnil(L,-1)) { lua_pop(L,3); dt_lua_unlock(has_lock); return; } luaA_push_typeid(L,self->parameter_lua_type,data); luaA_push_typeid(L,format->parameter_lua_type,fdata); GList* imgids =*images; lua_newtable(L); while(imgids) { luaA_push(L,dt_lua_image_t,&(imgids->data)); luaL_ref(L,-2); imgids = g_list_next(imgids); } lua_pushboolean(L,high_quality); lua_storage_t *d = (lua_storage_t*) data; if(!d->data_created) { lua_pushlightuserdata(L,d); lua_newtable(L); lua_settable(L,LUA_REGISTRYINDEX); d->data_created = true; } lua_pushlightuserdata(L,data); lua_gettable(L,LUA_REGISTRYINDEX); dt_lua_do_chunk_silent(L,5,1); if(!lua_isnoneornil(L,-1)) { luaL_checktype(L,-1,LUA_TTABLE); g_list_free(*images); GList *new_images=NULL; lua_pushnil(L); while(lua_next(L,-2)){ dt_lua_image_t imgid; luaA_to(L,dt_lua_image_t,&imgid,-1); new_images = g_list_prepend(new_images,GINT_TO_POINTER(imgid)); lua_pop(L,1); } new_images = g_list_reverse(new_images); *images = new_images; } lua_pop(L,3); dt_lua_unlock(has_lock); }
int get_group(lua_State *L) { dt_lua_image_t first_image; luaA_to(L,dt_lua_image_t,&first_image,1); const dt_image_t *cimg = dt_image_cache_read_get(darktable.image_cache, first_image); int group_id = cimg->group_id; dt_image_cache_read_release(darktable.image_cache, cimg); sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select id from images where group_id = ?1", -1, &stmt, NULL); DT_DEBUG_SQLITE3_BIND_INT(stmt, 1, group_id); lua_newtable(L); while(sqlite3_step(stmt) == SQLITE_ROW) { int imgid = sqlite3_column_int(stmt, 0); luaA_push(L,dt_lua_image_t,&imgid); luaL_ref(L,-2); } luaA_push(L,dt_lua_image_t,&group_id); lua_setfield(L,-2,"leader"); return 1; }
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; }
static int act_on_cb(lua_State *L) { int32_t imgid = dt_view_get_image_to_act_on(); lua_newtable(L); if(imgid != -1) { luaA_push(L,dt_lua_image_t,&imgid); luaL_ref(L,-2); return 1; } else { GList *image = dt_collection_get_selected(darktable.collection, -1); while(image) { luaA_push(L,dt_lua_image_t,&image->data); luaL_ref(L,-2); image = g_list_delete_link(image, image); } return 1; } }
static int tag_lib_find(lua_State *L) { const char * name = luaL_checkstring(L,1); dt_lua_tag_t tagid; if(!dt_tag_exists(name,&tagid)) { lua_pushnil(L); return 1; } luaA_push(L,dt_lua_tag_t,&tagid); return 1; }
static int32_t on_mouse_over_image_changed_callback_job(dt_job_t *job) { dt_lua_lock(); on_mouse_over_image_changed_callback_data_t *t = dt_control_job_get_params(job); int n_params = (t->imgid != -1); if(n_params) luaA_push(darktable.lua_state.state, dt_lua_image_t, &t->imgid); dt_lua_event_trigger(darktable.lua_state.state, "mouse-over-image-changed", n_params); free(t); dt_lua_unlock(); return 0; }
static int direction_member(lua_State *L) { dt_lib_module_t *self = *(dt_lib_module_t **)lua_touserdata(L, 1); dt_lib_snapshots_t *d = (dt_lib_snapshots_t *)self->data; if(lua_gettop(L) != 3) { snapshot_direction_t result; if(!d->vertical && !d->inverted) { result = SNS_TOP; } else if(!d->vertical && d->inverted) { result = SNS_BOTTOM; } else if(d->vertical && !d->inverted) { result = SNS_LEFT; } else { result = SNS_RIGHT; } luaA_push(L, snapshot_direction_t, &result); return 1; } else { snapshot_direction_t direction; luaA_to(L, snapshot_direction_t, &direction, 3); if(direction == SNS_TOP) { d->vertical = FALSE; d->inverted = FALSE; } else if(direction == SNS_BOTTOM) { d->vertical = FALSE; d->inverted = TRUE; } else if(direction == SNS_LEFT) { d->vertical = TRUE; d->inverted = FALSE; } else { d->vertical = TRUE; d->inverted = TRUE; } return 0; } }
static int layout_cb(lua_State *L) { dt_lib_module_t *self = lua_touserdata(L, lua_upvalueindex(1)); const dt_lighttable_layout_t tmp = _lib_lighttable_get_layout(self); if(lua_gettop(L) > 0){ dt_lighttable_layout_t value; luaA_to(L,dt_lighttable_layout_t,&value,1); _lib_lighttable_set_layout(self, value); } luaA_push(L, dt_lighttable_layout_t, &tmp); return 1; }
static int32_t on_mouse_over_image_changed_callback_job(dt_job_t *job) { gboolean has_lock = dt_lua_lock(); on_mouse_over_image_changed_callback_data_t *t = dt_control_job_get_params(job); int n_params = (t->imgid != -1); if(n_params) luaA_push(darktable.lua_state.state, dt_lua_image_t, &t->imgid); dt_lua_event_trigger(darktable.lua_state.state, "mouse-over-image-changed", n_params); free(t); // i am not sure if the free() may happen before the dt_lua_event_trigger as a pointer to the imgid // inside of it is pushed to the lua stack dt_lua_unlock(has_lock); return 0; }
static int number_member(lua_State *L) { dt_lib_module_t * self = *(dt_lib_module_t**)lua_touserdata(L,1); dt_lib_snapshots_t *d = (dt_lib_snapshots_t *)self->data; dt_lua_lib_check_error(L,self); int index = luaL_checkinteger(L,2); if(index > d->num_snapshots || index < 1) { return luaL_error(L,"Accessing a non-existant snapshot"); } index = index-1; luaA_push(L,dt_lua_snapshot_t,&index); return 1; }
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 int orientation_member(lua_State *L) { lua_box box; luaA_to(L,lua_box,&box,1); dt_lua_orientation_t orientation; if(lua_gettop(L) > 2) { luaA_to(L,dt_lua_orientation_t,&orientation,3); gtk_orientable_set_orientation(GTK_ORIENTABLE(box->widget),orientation); return 0; } orientation = gtk_orientable_get_orientation(GTK_ORIENTABLE(box->widget)); luaA_push(L,dt_lua_orientation_t,&orientation); return 1; }