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 "gtkcolorpickerkwinprivate.h" |
21 | #include <gio/gio.h> |
22 | |
23 | struct _GtkColorPickerKwin |
24 | { |
25 | GObject parent_instance; |
26 | |
27 | GDBusProxy *kwin_proxy; |
28 | GTask *task; |
29 | }; |
30 | |
31 | struct _GtkColorPickerKwinClass |
32 | { |
33 | GObjectClass parent_class; |
34 | }; |
35 | |
36 | static GInitableIface *initable_parent_iface; |
37 | static void gtk_color_picker_kwin_initable_iface_init (GInitableIface *iface); |
38 | static void gtk_color_picker_kwin_iface_init (GtkColorPickerInterface *iface); |
39 | |
40 | G_DEFINE_TYPE_WITH_CODE (GtkColorPickerKwin, gtk_color_picker_kwin, G_TYPE_OBJECT, |
41 | G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE, gtk_color_picker_kwin_initable_iface_init) |
42 | G_IMPLEMENT_INTERFACE (GTK_TYPE_COLOR_PICKER, gtk_color_picker_kwin_iface_init)) |
43 | |
44 | static gboolean |
45 | gtk_color_picker_kwin_initable_init (GInitable *initable, |
46 | GCancellable *cancellable, |
47 | GError **error) |
48 | { |
49 | GtkColorPickerKwin *picker = GTK_COLOR_PICKER_KWIN (ptr: initable); |
50 | char *owner; |
51 | |
52 | picker->kwin_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.kde.KWin" , |
56 | object_path: "/ColorPicker" , |
57 | interface_name: "org.kde.kwin.ColorPicker" , |
58 | NULL, |
59 | error); |
60 | |
61 | if (picker->kwin_proxy == NULL) |
62 | { |
63 | g_debug ("Failed to create kwin colorpicker proxy" ); |
64 | return FALSE; |
65 | } |
66 | |
67 | owner = g_dbus_proxy_get_name_owner (proxy: picker->kwin_proxy); |
68 | if (owner == NULL) |
69 | { |
70 | g_debug ("org.kde.kwin.ColorPicker not provided" ); |
71 | g_clear_object (&picker->kwin_proxy); |
72 | return FALSE; |
73 | } |
74 | g_free (mem: owner); |
75 | |
76 | return TRUE; |
77 | } |
78 | |
79 | static void |
80 | gtk_color_picker_kwin_initable_iface_init (GInitableIface *iface) |
81 | { |
82 | initable_parent_iface = g_type_interface_peek_parent (g_iface: iface); |
83 | iface->init = gtk_color_picker_kwin_initable_init; |
84 | } |
85 | |
86 | static void |
87 | gtk_color_picker_kwin_init (GtkColorPickerKwin *picker) |
88 | { |
89 | } |
90 | |
91 | static void |
92 | gtk_color_picker_kwin_finalize (GObject *object) |
93 | { |
94 | GtkColorPickerKwin *picker = GTK_COLOR_PICKER_KWIN (ptr: object); |
95 | |
96 | g_clear_object (&picker->kwin_proxy); |
97 | |
98 | G_OBJECT_CLASS (gtk_color_picker_kwin_parent_class)->finalize (object); |
99 | } |
100 | |
101 | static void |
102 | gtk_color_picker_kwin_class_init (GtkColorPickerKwinClass *class) |
103 | { |
104 | GObjectClass *object_class = G_OBJECT_CLASS (class); |
105 | |
106 | object_class->finalize = gtk_color_picker_kwin_finalize; |
107 | } |
108 | |
109 | GtkColorPicker * |
110 | gtk_color_picker_kwin_new (void) |
111 | { |
112 | return GTK_COLOR_PICKER (g_initable_new (GTK_TYPE_COLOR_PICKER_KWIN, NULL, NULL, NULL)); |
113 | } |
114 | |
115 | static void |
116 | color_picked (GObject *source, |
117 | GAsyncResult *res, |
118 | gpointer data) |
119 | { |
120 | GtkColorPickerKwin *picker = GTK_COLOR_PICKER_KWIN (ptr: data); |
121 | GError *error = NULL; |
122 | GVariant *ret; |
123 | |
124 | ret = g_dbus_proxy_call_finish (proxy: picker->kwin_proxy, res, error: &error); |
125 | |
126 | if (ret == NULL) |
127 | { |
128 | g_task_return_error (task: picker->task, error); |
129 | } |
130 | else |
131 | { |
132 | GdkRGBA c; |
133 | guint32 color; |
134 | |
135 | g_variant_get (value: ret, format_string: "(u)" , &color); |
136 | |
137 | c.blue = ( color & 0xff) / 255.0; |
138 | c.green = ((color >> 8) & 0xff) / 255.0; |
139 | c.red = ((color >> 16) & 0xff) / 255.0; |
140 | c.alpha = ((color >> 24) & 0xff) / 255.0; |
141 | |
142 | g_task_return_pointer (task: picker->task, result: gdk_rgba_copy (rgba: &c), result_destroy: (GDestroyNotify)gdk_rgba_free); |
143 | |
144 | g_variant_unref (value: ret); |
145 | } |
146 | |
147 | g_clear_object (&picker->task); |
148 | } |
149 | |
150 | static void |
151 | gtk_color_picker_kwin_pick (GtkColorPicker *cp, |
152 | GAsyncReadyCallback callback, |
153 | gpointer user_data) |
154 | { |
155 | GtkColorPickerKwin *picker = GTK_COLOR_PICKER_KWIN (ptr: cp); |
156 | |
157 | if (picker->task) |
158 | return; |
159 | |
160 | picker->task = g_task_new (source_object: picker, NULL, callback, callback_data: user_data); |
161 | |
162 | g_dbus_proxy_call (proxy: picker->kwin_proxy, |
163 | method_name: "pick" , |
164 | NULL, |
165 | flags: 0, |
166 | timeout_msec: -1, |
167 | NULL, |
168 | callback: color_picked, |
169 | user_data: picker); |
170 | } |
171 | |
172 | static GdkRGBA * |
173 | gtk_color_picker_kwin_pick_finish (GtkColorPicker *cp, |
174 | GAsyncResult *res, |
175 | GError **error) |
176 | { |
177 | g_return_val_if_fail (g_task_is_valid (res, cp), NULL); |
178 | |
179 | return g_task_propagate_pointer (G_TASK (res), error); |
180 | } |
181 | |
182 | static void |
183 | gtk_color_picker_kwin_iface_init (GtkColorPickerInterface *iface) |
184 | { |
185 | iface->pick = gtk_color_picker_kwin_pick; |
186 | iface->pick_finish = gtk_color_picker_kwin_pick_finish; |
187 | } |
188 | |