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 | |
23 | struct _GtkColorPickerShell |
24 | { |
25 | GObject parent_instance; |
26 | |
27 | GDBusProxy *shell_proxy; |
28 | GTask *task; |
29 | }; |
30 | |
31 | struct _GtkColorPickerShellClass |
32 | { |
33 | GObjectClass parent_class; |
34 | }; |
35 | |
36 | static GInitableIface *initable_parent_iface; |
37 | static void gtk_color_picker_shell_initable_iface_init (GInitableIface *iface); |
38 | static void gtk_color_picker_shell_iface_init (GtkColorPickerInterface *iface); |
39 | |
40 | G_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 | |
44 | static gboolean |
45 | gtk_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 | |
79 | static void |
80 | gtk_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 | |
86 | static void |
87 | gtk_color_picker_shell_init (GtkColorPickerShell *picker) |
88 | { |
89 | } |
90 | |
91 | static void |
92 | gtk_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 | |
101 | static void |
102 | gtk_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 | |
109 | GtkColorPicker * |
110 | gtk_color_picker_shell_new (void) |
111 | { |
112 | return GTK_COLOR_PICKER (g_initable_new (GTK_TYPE_COLOR_PICKER_SHELL, NULL, NULL, NULL)); |
113 | } |
114 | |
115 | static void |
116 | color_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 | |
149 | static void |
150 | gtk_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 | |
171 | static GdkRGBA * |
172 | gtk_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 | |
181 | static void |
182 | gtk_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 | |