1/* GTK - The GIMP Toolkit
2 * Copyright (C) 2018, Red Hat, Inc
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include "config.h"
19
20#include "gtkcolorpickershellprivate.h"
21#include <gio/gio.h>
22
23struct _GtkColorPickerShell
24{
25 GObject parent_instance;
26
27 GDBusProxy *shell_proxy;
28 GTask *task;
29};
30
31struct _GtkColorPickerShellClass
32{
33 GObjectClass parent_class;
34};
35
36static GInitableIface *initable_parent_iface;
37static void gtk_color_picker_shell_initable_iface_init (GInitableIface *iface);
38static void gtk_color_picker_shell_iface_init (GtkColorPickerInterface *iface);
39
40G_DEFINE_TYPE_WITH_CODE (GtkColorPickerShell, gtk_color_picker_shell, G_TYPE_OBJECT,
41 G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gtk_color_picker_shell_initable_iface_init)
42 G_IMPLEMENT_INTERFACE (GTK_TYPE_COLOR_PICKER, gtk_color_picker_shell_iface_init))
43
44static gboolean
45gtk_color_picker_shell_initable_init (GInitable *initable,
46 GCancellable *cancellable,
47 GError **error)
48{
49 GtkColorPickerShell *picker = GTK_COLOR_PICKER_SHELL (ptr: initable);
50 char *owner;
51
52 picker->shell_proxy = g_dbus_proxy_new_for_bus_sync (bus_type: G_BUS_TYPE_SESSION,
53 flags: G_DBUS_PROXY_FLAGS_NONE,
54 NULL,
55 name: "org.gnome.Shell.Screenshot",
56 object_path: "/org/gnome/Shell/Screenshot",
57 interface_name: "org.gnome.Shell.Screenshot",
58 NULL,
59 error);
60
61 if (picker->shell_proxy == NULL)
62 {
63 g_debug ("Failed to create shell screenshot proxy");
64 return FALSE;
65 }
66
67 owner = g_dbus_proxy_get_name_owner (proxy: picker->shell_proxy);
68 if (owner == NULL)
69 {
70 g_debug ("org.gnome.Shell.Screenshot not provided");
71 g_clear_object (&picker->shell_proxy);
72 return FALSE;
73 }
74 g_free (mem: owner);
75
76 return TRUE;
77}
78
79static void
80gtk_color_picker_shell_initable_iface_init (GInitableIface *iface)
81{
82 initable_parent_iface = g_type_interface_peek_parent (g_iface: iface);
83 iface->init = gtk_color_picker_shell_initable_init;
84}
85
86static void
87gtk_color_picker_shell_init (GtkColorPickerShell *picker)
88{
89}
90
91static void
92gtk_color_picker_shell_finalize (GObject *object)
93{
94 GtkColorPickerShell *picker = GTK_COLOR_PICKER_SHELL (ptr: object);
95
96 g_clear_object (&picker->shell_proxy);
97
98 G_OBJECT_CLASS (gtk_color_picker_shell_parent_class)->finalize (object);
99}
100
101static void
102gtk_color_picker_shell_class_init (GtkColorPickerShellClass *class)
103{
104 GObjectClass *object_class = G_OBJECT_CLASS (class);
105
106 object_class->finalize = gtk_color_picker_shell_finalize;
107}
108
109GtkColorPicker *
110gtk_color_picker_shell_new (void)
111{
112 return GTK_COLOR_PICKER (g_initable_new (GTK_TYPE_COLOR_PICKER_SHELL, NULL, NULL, NULL));
113}
114
115static void
116color_picked (GObject *source,
117 GAsyncResult *res,
118 gpointer data)
119{
120 GtkColorPickerShell *picker = GTK_COLOR_PICKER_SHELL (ptr: data);
121 GError *error = NULL;
122 GVariant *ret, *dict;
123
124 ret = g_dbus_proxy_call_finish (proxy: picker->shell_proxy, res, error: &error);
125
126 if (ret == NULL)
127 {
128 g_task_return_error (task: picker->task, error);
129 }
130 else
131 {
132 double d1, d2, d3;
133
134 g_variant_get (value: ret, format_string: "(@a{sv})", &dict);
135
136 if (!g_variant_lookup (dictionary: dict, key: "color", format_string: "(ddd)", &d1, &d2, &d3))
137 g_task_return_new_error (task: picker->task, G_IO_ERROR, code: G_IO_ERROR_FAILED, format: "No color received");
138 else
139 g_task_return_pointer (task: picker->task,
140 result: gdk_rgba_copy (rgba: &(GdkRGBA){d1, d2, d3, 1.0f}), result_destroy: (GDestroyNotify)gdk_rgba_free);
141
142 g_variant_unref (value: dict);
143 g_variant_unref (value: ret);
144 }
145
146 g_clear_object (&picker->task);
147}
148
149static void
150gtk_color_picker_shell_pick (GtkColorPicker *cp,
151 GAsyncReadyCallback callback,
152 gpointer user_data)
153{
154 GtkColorPickerShell *picker = GTK_COLOR_PICKER_SHELL (ptr: cp);
155
156 if (picker->task)
157 return;
158
159 picker->task = g_task_new (source_object: picker, NULL, callback, callback_data: user_data);
160
161 g_dbus_proxy_call (proxy: picker->shell_proxy,
162 method_name: "PickColor",
163 NULL,
164 flags: 0,
165 timeout_msec: -1,
166 NULL,
167 callback: color_picked,
168 user_data: picker);
169}
170
171static GdkRGBA *
172gtk_color_picker_shell_pick_finish (GtkColorPicker *cp,
173 GAsyncResult *res,
174 GError **error)
175{
176 g_return_val_if_fail (g_task_is_valid (res, cp), NULL);
177
178 return g_task_propagate_pointer (G_TASK (res), error);
179}
180
181static void
182gtk_color_picker_shell_iface_init (GtkColorPickerInterface *iface)
183{
184 iface->pick = gtk_color_picker_shell_pick;
185 iface->pick_finish = gtk_color_picker_shell_pick_finish;
186}
187

source code of gtk/gtk/gtkcolorpickershell.c