Skip to content

Commit

Permalink
Add initial dbus server functionality
Browse files Browse the repository at this point in the history
Currently you can quit darktable and tell it to load images/folders. It
also passes the images/folders to load passed on the command line to the
running instance when it detects that there is another one active
already.
  • Loading branch information
houz committed Jan 14, 2013
1 parent 62cbe08 commit 543e664
Show file tree
Hide file tree
Showing 7 changed files with 311 additions and 15 deletions.
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ FILE(GLOB SOURCE_FILES
"common/curve_tools.c"
"common/darktable.c"
"common/database.c"
"common/dbus.c"
"common/exif.cc"
"common/film.c"
"common/file_location.c"
Expand Down
82 changes: 70 additions & 12 deletions src/common/darktable.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
This file is part of darktable,
copyright (c) 2009--2012 johannes hanika.
copyright (c) 2010--2012 henrik andersson.
copyright (c) 2010--2012 tobias ellinghaus.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -59,6 +60,7 @@
#ifdef HAVE_GRAPHICSMAGICK
#include <magick/api.h>
#endif
#include "dbus.h"

#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__DragonFly__)
#include <malloc.h>
Expand Down Expand Up @@ -310,13 +312,10 @@ static void strip_semicolons_from_keymap(const char* path)
g_object_unref(gpathtmp);
}

int dt_load_from_string(const gchar* input, gboolean open_image_in_dr)
static gchar * dt_make_path_absolute(const gchar * input)
{
int id = 0;
if(input == NULL || input[0] == '\0')
return 0;
gchar *filename = NULL;

char* filename;
if(g_str_has_prefix(input, "file://")) // in this case we should take care of %XX encodings in the string (for example %20 = ' ')
{
input += strlen("file://");
Expand All @@ -333,16 +332,32 @@ int dt_load_from_string(const gchar* input, gboolean open_image_in_dr)
filename = (char*)g_malloc(sizeof(char)*MAXPATHLEN);
if(realpath(tmp_filename, filename) == NULL)
{
dt_control_log(_("found strange path `%s'"), tmp_filename);
g_free(current_dir);
g_free(tmp_filename);
g_free(filename);
return 0;
return NULL;
}
g_free(current_dir);
g_free(tmp_filename);
}

return filename;
}

int dt_load_from_string(const gchar* input, gboolean open_image_in_dr)
{
int id = 0;
if(input == NULL || input[0] == '\0')
return 0;

char* filename = dt_make_path_absolute(input);

if(filename == NULL)
{
dt_control_log(_("found strange path `%s'"), input);
return 0;
}

if(g_file_test(filename, G_FILE_TEST_IS_DIR))
{
// import a directory into a film roll
Expand Down Expand Up @@ -581,6 +596,43 @@ int dt_init(int argc, char *argv[], const int init_gui)
printf("ERROR : cannot open database\n");
return 1;
}
else if(dt_database_get_already_locked(darktable.db))
{
// send the images to the other instance via dbus
if(images_to_load)
{
GSList *p = images_to_load;

// get a connection!
GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SESSION,NULL, NULL);

while (p != NULL)
{
// make the filename absolute ...
gchar *filename = dt_make_path_absolute((gchar*)p->data);
if(filename == NULL) continue;
// ... and send it to the running instance of darktable
g_dbus_connection_call_sync(connection,
"org.darktable.service",
"/darktable",
"org.darktable.service.Remote",
"Open",
g_variant_new ("(s)", filename),
NULL,
G_DBUS_CALL_FLAGS_NONE,
-1,
NULL,
NULL);
p = g_slist_next(p);
g_free(filename);
}

g_slist_free(images_to_load);
g_object_unref(connection);
}

return 1;
}

// Initialize the signal system
darktable.signals = dt_control_signal_init();
Expand Down Expand Up @@ -717,21 +769,25 @@ int dt_init(int argc, char *argv[], const int init_gui)
else
gtk_accel_map_save(keyfile); // Save the default keymap if none is present

// I doubt that connecting to dbus for darktable-cli makes sense
darktable.dbus = dt_dbus_init();

// load image(s) specified on cmdline
if (images_to_load)
int id = 0;
if(images_to_load)
{
// If only one image is listed, attempt to load it in darkroom
gboolean load_in_dr = (g_slist_next(images_to_load) == NULL);
GSList *p = images_to_load;

while (p != NULL)
{
dt_load_from_string((gchar*)p->data, load_in_dr);
p = g_slist_next(p);
id = MAX(id, dt_load_from_string((gchar*)p->data, load_in_dr));
p = g_slist_next(p);
}

if (!load_in_dr)
dt_ctl_switch_mode_to(DT_LIBRARY);
if (!load_in_dr || id == 0)
dt_ctl_switch_mode_to(DT_LIBRARY);

g_slist_free(images_to_load);
}
Expand All @@ -758,6 +814,8 @@ void dt_cleanup()

if(init_gui)
{
dt_dbus_destroy(darktable.dbus);

dt_control_write_config(darktable.control);
dt_control_shutdown(darktable.control);

Expand Down
4 changes: 3 additions & 1 deletion src/common/darktable.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
This file is part of darktable,
copyright (c) 2009--2012 johannes hanika.
copyright (c) 2010--2012 tobias ellinghaus.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -172,7 +173,7 @@ typedef struct darktable_t
struct dt_image_cache_t *image_cache;
struct dt_bauhaus_t *bauhaus;
const struct dt_database_t *db;
const struct dt_fswatch_t *fswatch;
const struct dt_fswatch_t *fswatch;
const struct dt_pwstorage_t *pwstorage;
const struct dt_camctl_t *camctl;
const struct dt_collection_t *collection;
Expand All @@ -181,6 +182,7 @@ typedef struct darktable_t
struct dt_imageio_t *imageio;
struct dt_opencl_t *opencl;
struct dt_blendop_t *blendop;
struct dt_dbus_t *dbus;
dt_pthread_mutex_t db_insert;
dt_pthread_mutex_t plugin_threadsafe;
dt_pthread_mutex_t capabilities_threadsafe;
Expand Down
11 changes: 9 additions & 2 deletions src/common/database.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
This file is part of darktable,
copyright (c) 2011 henrik andersson.
copyright (c) 2012 tobias ellinghaus.
darktable is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand Down Expand Up @@ -29,6 +30,7 @@
typedef struct dt_database_t
{
gboolean is_new_database;
gboolean already_locked;

/* database filename */
gchar *dbfilename;
Expand Down Expand Up @@ -111,8 +113,8 @@ dt_database_t *dt_database_init(char *alternative)
fprintf(stderr, "[init] database is locked, probably another process is already using it\n");
sqlite3_close(db->handle);
g_free(dbname);
g_free(db);
return NULL;
db->already_locked = TRUE;
return db;
}

/* attach a memory database to db connection for use with temporary tables
Expand Down Expand Up @@ -195,6 +197,11 @@ static void _database_delete_mipmaps_files()
}
}

gboolean dt_database_get_already_locked(const dt_database_t *db)
{
return db->already_locked;
}

// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
// vim: shiftwidth=2 expandtab tabstop=2 cindent
// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-space on;
2 changes: 2 additions & 0 deletions src/common/database.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ struct sqlite3 *dt_database_get(const struct dt_database_t *);
gboolean dt_database_is_new(const struct dt_database_t *db);
/** Returns database path */
const gchar *dt_database_get_path(const struct dt_database_t *db);
/** test if database was already locked by another instance */
gboolean dt_database_get_already_locked(const struct dt_database_t *db);
#endif
// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.sh
// vim: shiftwidth=2 expandtab tabstop=2 cindent
Expand Down
Loading

0 comments on commit 543e664

Please sign in to comment.