1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program 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
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 
20 #include <gegl.h>
21 #include <gtk/gtk.h>
22 
23 #include "libgimpcolor/gimpcolor.h"
24 #include "libgimpconfig/gimpconfig.h"
25 #include "libgimpbase/gimpbase.h"
26 
27 #include "widgets-types.h"
28 
29 #include "config/gimpguiconfig.h"
30 
31 #include "core/gimp.h"
32 #include "core/gimpcontext.h"
33 #include "core/gimpdatafactory.h"
34 #include "core/gimperror.h"
35 #include "core/gimpgradient.h"
36 #include "core/gimplist.h"
37 #include "core/gimppattern.h"
38 #include "core/gimptoolinfo.h"
39 
40 #include "gimpdeviceinfo.h"
41 #include "gimpdevicemanager.h"
42 #include "gimpdevices.h"
43 
44 #include "gimp-intl.h"
45 
46 
47 #define GIMP_DEVICE_MANAGER_DATA_KEY "gimp-device-manager"
48 
49 
50 static gboolean devicerc_deleted = FALSE;
51 
52 
53 /*  public functions  */
54 
55 void
gimp_devices_init(Gimp * gimp)56 gimp_devices_init (Gimp *gimp)
57 {
58   GimpDeviceManager *manager;
59 
60   g_return_if_fail (GIMP_IS_GIMP (gimp));
61 
62   manager = g_object_get_data (G_OBJECT (gimp), GIMP_DEVICE_MANAGER_DATA_KEY);
63 
64   g_return_if_fail (manager == NULL);
65 
66   manager = gimp_device_manager_new (gimp);
67 
68   g_object_set_data_full (G_OBJECT (gimp),
69                           GIMP_DEVICE_MANAGER_DATA_KEY, manager,
70                           (GDestroyNotify) g_object_unref);
71 }
72 
73 void
gimp_devices_exit(Gimp * gimp)74 gimp_devices_exit (Gimp *gimp)
75 {
76   GimpDeviceManager *manager;
77 
78   g_return_if_fail (GIMP_IS_GIMP (gimp));
79 
80   manager = gimp_devices_get_manager (gimp);
81 
82   g_return_if_fail (GIMP_IS_DEVICE_MANAGER (manager));
83 
84   g_object_set_data (G_OBJECT (gimp), GIMP_DEVICE_MANAGER_DATA_KEY, NULL);
85 }
86 
87 void
gimp_devices_restore(Gimp * gimp)88 gimp_devices_restore (Gimp *gimp)
89 {
90   GimpDeviceManager *manager;
91   GList             *list;
92   GFile             *file;
93   GError            *error = NULL;
94 
95   g_return_if_fail (GIMP_IS_GIMP (gimp));
96 
97   manager = gimp_devices_get_manager (gimp);
98 
99   g_return_if_fail (GIMP_IS_DEVICE_MANAGER (manager));
100 
101   for (list = GIMP_LIST (manager)->queue->head;
102        list;
103        list = g_list_next (list))
104     {
105       GimpDeviceInfo *device_info = list->data;
106 
107       gimp_device_info_save_tool (device_info);
108       gimp_device_info_set_default_tool (device_info);
109     }
110 
111   file = gimp_directory_file ("devicerc", NULL);
112 
113   if (gimp->be_verbose)
114     g_print ("Parsing '%s'\n", gimp_file_get_utf8_name (file));
115 
116   if (! gimp_config_deserialize_gfile (GIMP_CONFIG (manager),
117                                        file,
118                                        gimp,
119                                        &error))
120     {
121       if (error->code != GIMP_CONFIG_ERROR_OPEN_ENOENT)
122         gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
123 
124       g_error_free (error);
125       /* don't bail out here */
126     }
127 
128   g_object_unref (file);
129 
130   for (list = GIMP_LIST (manager)->queue->head;
131        list;
132        list = g_list_next (list))
133     {
134       GimpDeviceInfo *device_info = list->data;
135 
136       if (! GIMP_TOOL_PRESET (device_info)->tool_options)
137         {
138           gimp_device_info_save_tool (device_info);
139 
140           g_printerr ("%s: set default tool on loaded GimpDeviceInfo without tool options: %s\n",
141                       G_STRFUNC, gimp_object_get_name (device_info));
142         }
143     }
144 
145   if (! GIMP_GUI_CONFIG (gimp->config)->devices_share_tool)
146     {
147       GimpDeviceInfo *current_device;
148 
149       current_device = gimp_device_manager_get_current_device (manager);
150 
151       gimp_device_info_restore_tool (current_device);
152     }
153 }
154 
155 void
gimp_devices_save(Gimp * gimp,gboolean always_save)156 gimp_devices_save (Gimp     *gimp,
157                    gboolean  always_save)
158 {
159   GimpDeviceManager *manager;
160   GFile             *file;
161   GError            *error = NULL;
162 
163   g_return_if_fail (GIMP_IS_GIMP (gimp));
164 
165   manager = gimp_devices_get_manager (gimp);
166 
167   g_return_if_fail (GIMP_IS_DEVICE_MANAGER (manager));
168 
169   if (devicerc_deleted && ! always_save)
170     return;
171 
172   file = gimp_directory_file ("devicerc", NULL);
173 
174   if (gimp->be_verbose)
175     g_print ("Writing '%s'\n", gimp_file_get_utf8_name (file));
176 
177   if (! GIMP_GUI_CONFIG (gimp->config)->devices_share_tool)
178     {
179       GimpDeviceInfo *current_device;
180 
181       current_device = gimp_device_manager_get_current_device (manager);
182 
183       gimp_device_info_save_tool (current_device);
184     }
185 
186   if (! gimp_config_serialize_to_gfile (GIMP_CONFIG (manager),
187                                         file,
188                                         "GIMP devicerc",
189                                         "end of devicerc",
190                                         NULL,
191                                         &error))
192     {
193       gimp_message_literal (gimp, NULL, GIMP_MESSAGE_ERROR, error->message);
194       g_error_free (error);
195     }
196 
197   g_object_unref (file);
198 
199   devicerc_deleted = FALSE;
200 }
201 
202 gboolean
gimp_devices_clear(Gimp * gimp,GError ** error)203 gimp_devices_clear (Gimp    *gimp,
204                     GError **error)
205 {
206   GimpDeviceManager *manager;
207   GFile             *file;
208   GError            *my_error = NULL;
209   gboolean           success  = TRUE;
210 
211   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
212 
213   manager = gimp_devices_get_manager (gimp);
214 
215   g_return_val_if_fail (GIMP_IS_DEVICE_MANAGER (manager), FALSE);
216 
217   file = gimp_directory_file ("devicerc", NULL);
218 
219   if (! g_file_delete (file, NULL, &my_error) &&
220       my_error->code != G_IO_ERROR_NOT_FOUND)
221     {
222       success = FALSE;
223 
224       g_set_error (error, GIMP_ERROR, GIMP_FAILED,
225                    _("Deleting \"%s\" failed: %s"),
226                    gimp_file_get_utf8_name (file), my_error->message);
227     }
228   else
229     {
230       devicerc_deleted = TRUE;
231     }
232 
233   g_clear_error (&my_error);
234   g_object_unref (file);
235 
236   return success;
237 }
238 
239 GimpDeviceManager *
gimp_devices_get_manager(Gimp * gimp)240 gimp_devices_get_manager (Gimp *gimp)
241 {
242   GimpDeviceManager *manager;
243 
244   g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
245 
246   manager = g_object_get_data (G_OBJECT (gimp), GIMP_DEVICE_MANAGER_DATA_KEY);
247 
248   g_return_val_if_fail (GIMP_IS_DEVICE_MANAGER (manager), NULL);
249 
250   return manager;
251 }
252 
253 void
gimp_devices_add_widget(Gimp * gimp,GtkWidget * widget)254 gimp_devices_add_widget (Gimp      *gimp,
255                          GtkWidget *widget)
256 {
257   g_return_if_fail (GIMP_IS_GIMP (gimp));
258   g_return_if_fail (GTK_IS_WIDGET (widget));
259 
260   gtk_widget_set_extension_events (widget, GDK_EXTENSION_EVENTS_ALL);
261 
262   g_signal_connect (widget, "motion-notify-event",
263                     G_CALLBACK (gimp_devices_check_callback),
264                     gimp);
265 }
266 
267 gboolean
gimp_devices_check_callback(GtkWidget * widget,GdkEvent * event,Gimp * gimp)268 gimp_devices_check_callback (GtkWidget *widget,
269                              GdkEvent  *event,
270                              Gimp      *gimp)
271 {
272   g_return_val_if_fail (event != NULL, FALSE);
273   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
274 
275   if (! gimp->busy)
276     gimp_devices_check_change (gimp, event);
277 
278   return FALSE;
279 }
280 
281 gboolean
gimp_devices_check_change(Gimp * gimp,GdkEvent * event)282 gimp_devices_check_change (Gimp     *gimp,
283                            GdkEvent *event)
284 {
285   GimpDeviceManager *manager;
286   GdkDevice         *device;
287   GimpDeviceInfo    *device_info;
288   GtkWidget         *source;
289 
290   g_return_val_if_fail (GIMP_IS_GIMP (gimp), FALSE);
291   g_return_val_if_fail (event != NULL, FALSE);
292 
293   manager = gimp_devices_get_manager (gimp);
294 
295   g_return_val_if_fail (GIMP_IS_DEVICE_MANAGER (manager), FALSE);
296 
297   /* It is possible that the event was propagated from a widget that does not
298      want extension events and therefore always sends core pointer events.
299      This can cause a false switch to the core pointer device. */
300 
301   source = gtk_get_event_widget (event);
302 
303   if (source &&
304       gtk_widget_get_extension_events (source) == GDK_EXTENSION_EVENTS_NONE)
305     return FALSE;
306 
307   switch (event->type)
308     {
309     case GDK_MOTION_NOTIFY:
310       device = ((GdkEventMotion *) event)->device;
311       break;
312 
313     case GDK_BUTTON_PRESS:
314     case GDK_2BUTTON_PRESS:
315     case GDK_3BUTTON_PRESS:
316     case GDK_BUTTON_RELEASE:
317       device = ((GdkEventButton *) event)->device;
318       break;
319 
320     case GDK_PROXIMITY_IN:
321     case GDK_PROXIMITY_OUT:
322       device = ((GdkEventProximity *) event)->device;
323       break;
324 
325     case GDK_SCROLL:
326       device = ((GdkEventScroll *) event)->device;
327       break;
328 
329     default:
330       device = gimp_device_manager_get_current_device (manager)->device;
331       break;
332     }
333 
334   device_info = gimp_device_info_get_by_device (device);
335 
336   if (device_info != gimp_device_manager_get_current_device (manager))
337     {
338       gimp_device_manager_set_current_device (manager, device_info);
339       return TRUE;
340     }
341 
342   return FALSE;
343 }
344