Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
dbus.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2013-2017 Tobias Ellinghaus.
4 Copyright (C) 2014, 2016 Jérémy Rosen.
5 Copyright (C) 2014-2016 Roman Lebedev.
6 Copyright (C) 2019 jakubfi.
7 Copyright (C) 2020 Pascal Obry.
8 Copyright (C) 2021 Ralf Brown.
9 Copyright (C) 2022 Martin Bařinka.
10 Copyright (C) 2023 Aurélien PIERRE.
11
12 darktable is free software: you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation, either version 3 of the License, or
15 (at your option) any later version.
16
17 darktable is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with darktable. If not, see <http://www.gnu.org/licenses/>.
24*/
25
26#include "common/dbus.h"
27#include "common/darktable.h"
28#include "control/conf.h"
29#include "control/control.h"
31
32/* Introspection data for the service we are exporting */
33static const gchar introspection_xml[] = "<node>"
34 " <interface name='org.darktable.service.Remote'>"
35 " <method name='Quit' />"
36 " <method name='Open'>"
37 " <arg type='s' name='FileName' direction='in'/>"
38 " <arg type='i' name='id' direction='out' />"
39 " </method>"
40 " <property type='s' name='DataDir' access='read'/>"
41 " <property type='s' name='ConfigDir' access='read'/>"
42 " <property type='b' name='LuaEnabled' access='read'/>"
43 " </interface>"
44 "</node>";
45
46static void _handle_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path,
47 const gchar *interface_name, const gchar *method_name, GVariant *parameters,
48 GDBusMethodInvocation *invocation, gpointer user_data)
49{
50 if(!g_strcmp0(method_name, "Quit"))
51 {
52 g_dbus_method_invocation_return_value(invocation, NULL);
54 }
55 else if(!g_strcmp0(method_name, "Open"))
56 {
57 const gchar *filename;
58 g_variant_get(parameters, "(&s)", &filename);
59 int32_t id = dt_load_from_string(filename, TRUE, NULL);
60 g_dbus_method_invocation_return_value(invocation, g_variant_new("(i)", id));
61 }
62}
63
64// TODO: expose the conf? partly? completely?
65
66static GVariant *_handle_get_property(GDBusConnection *connection, const gchar *sender,
67 const gchar *object_path, const gchar *interface_name,
68 const gchar *property_name, GError **error, gpointer user_data)
69{
70 GVariant *ret;
71
72 ret = NULL;
73 if(!g_strcmp0(property_name, "DataDir"))
74 {
75 gchar datadir[PATH_MAX] = { 0 };
76 dt_loc_get_datadir(datadir, sizeof(datadir));
77 ret = g_variant_new_string(datadir);
78 }
79 else if(!g_strcmp0(property_name, "ConfigDir"))
80 {
81 gchar configdir[PATH_MAX] = { 0 };
82 dt_loc_get_user_config_dir(configdir, sizeof(configdir));
83 ret = g_variant_new_string(configdir);
84 }
85 else if(!g_strcmp0(property_name, "LuaEnabled"))
86 {
87 ret = g_variant_new_boolean(FALSE);
88 }
89 return ret;
90}
91
92// static gboolean
93// _handle_set_property(GDBusConnection *connection,
94// const gchar *sender,
95// const gchar *object_path,
96// const gchar *interface_name,
97// const gchar *property_name,
98// GVariant *value,
99// GError **error,
100// gpointer user_data)
101// {
102// return IS_NULL_PTR(*error);
103// }
104
105static const GDBusInterfaceVTable interface_vtable = { _handle_method_call, _handle_get_property,
106 // _handle_set_property
107 NULL };
108
109static void _on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
110{
111 dt_dbus_t *dbus = (dt_dbus_t *)user_data;
112
113 dbus->registration_id
114 = g_dbus_connection_register_object(connection, "/darktable", dbus->introspection_data->interfaces[0],
115 &interface_vtable, dbus, /* user_data */
116 NULL, /* user_data_free_func */
117 NULL); /* GError** */
118
119 if(dbus->registration_id == 0)
120 dbus->connected
121 = 0; // technically we are connected, but we are not exporting anything. or something like that
122}
123
124static void _on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
125{
126 dt_dbus_t *dbus = (dt_dbus_t *)user_data;
127 dbus->connected = 1;
128}
129
130static void _on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
131{
132 dt_dbus_t *dbus = (dt_dbus_t *)user_data;
133 dbus->connected = 0;
134}
135
137{
138 dt_dbus_t *dbus = (dt_dbus_t *)g_malloc0(sizeof(dt_dbus_t));
139 if(IS_NULL_PTR(dbus)) return NULL;
140
141 dbus->introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
142
143 if(IS_NULL_PTR(dbus->introspection_data)) return dbus;
144
145 dbus->owner_id = g_bus_own_name(G_BUS_TYPE_SESSION,
146 "org.darktable.service", // FIXME
147 G_BUS_NAME_OWNER_FLAGS_NONE, _on_bus_acquired, _on_name_acquired,
148 _on_name_lost, dbus, NULL);
149
150 dbus->dbus_connection = g_bus_get_sync(G_BUS_TYPE_SESSION, NULL, NULL);
151 g_object_set(G_OBJECT(dbus->dbus_connection), "exit-on-close", FALSE, (gchar *)0);
152
153 return dbus;
154}
155
156void dt_dbus_destroy(const dt_dbus_t *dbus)
157{
158 if(IS_NULL_PTR(dbus)) return;
159 g_bus_unown_name(dbus->owner_id);
160
161 if(dbus->introspection_data)
162 g_dbus_node_info_unref(dbus->introspection_data);
163
164 if(dbus->dbus_connection)
165 g_object_unref(G_OBJECT(dbus->dbus_connection));
166
167 dt_free(dbus);
168}
169
170gboolean dt_dbus_connected(const dt_dbus_t *dbus)
171{
172 return dbus->connected;
173}
174
175// clang-format off
176// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
177// vim: shiftwidth=2 expandtab tabstop=2 cindent
178// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
179// clang-format on
static void error(char *msg)
Definition ashift_lsd.c:202
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
char * name
void dt_control_quit()
Definition control.c:433
int dt_load_from_string(const gchar *input, gboolean open_image_in_dr, gboolean *single_image)
Definition darktable.c:328
#define dt_free(ptr)
Definition darktable.h:456
#define PATH_MAX
Definition darktable.h:1062
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition darktable.h:281
static void _on_bus_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
Definition dbus.c:109
static void _on_name_acquired(GDBusConnection *connection, const gchar *name, gpointer user_data)
Definition dbus.c:124
struct dt_dbus_t * dt_dbus_init()
Definition dbus.c:136
static void _on_name_lost(GDBusConnection *connection, const gchar *name, gpointer user_data)
Definition dbus.c:130
static void _handle_method_call(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *method_name, GVariant *parameters, GDBusMethodInvocation *invocation, gpointer user_data)
Definition dbus.c:46
static const gchar introspection_xml[]
Definition dbus.c:33
static GVariant * _handle_get_property(GDBusConnection *connection, const gchar *sender, const gchar *object_path, const gchar *interface_name, const gchar *property_name, GError **error, gpointer user_data)
Definition dbus.c:66
static const GDBusInterfaceVTable interface_vtable
Definition dbus.c:105
void dt_dbus_destroy(const dt_dbus_t *dbus)
Definition dbus.c:156
gboolean dt_dbus_connected(const dt_dbus_t *dbus)
Definition dbus.c:170
void dt_loc_get_datadir(char *datadir, size_t bufsize)
void dt_loc_get_user_config_dir(char *configdir, size_t bufsize)
GDBusConnection * dbus_connection
Definition dbus.h:38
GDBusNodeInfo * introspection_data
Definition dbus.h:33
int connected
Definition dbus.h:31
guint registration_id
Definition dbus.h:35
guint owner_id
Definition dbus.h:34