1 /* GIMP - The GNU Image Manipulation Program
2  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
3  *
4  * gimpcontrollermouse.c
5  * Copyright (C) 2004 Michael Natterer <mitch@gimp.org>
6  * Copyright (C) 2011 Mikael Magnusson <mikachu@src.gnome.org>
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include "config.h"
23 
24 #include <gegl.h>
25 #undef GDK_MULTIHEAD_SAFE /* for gdk_keymap_get_default() */
26 #include <gtk/gtk.h>
27 
28 #include "libgimpwidgets/gimpwidgets.h"
29 
30 #include "widgets-types.h"
31 
32 #include "gimpcontrollermouse.h"
33 #include "gimphelp-ids.h"
34 #include "gimpwidgets-utils.h"
35 
36 #include "gimp-intl.h"
37 
38 
39 typedef struct _MouseEvent MouseEvent;
40 
41 struct _MouseEvent
42 {
43   const guint      button;
44   const gchar     *modifier_string;
45   GdkModifierType  modifiers;
46   const gchar     *name;
47   const gchar     *blurb;
48 };
49 
50 
51 static void          gimp_controller_mouse_constructed     (GObject        *object);
52 
53 static gint          gimp_controller_mouse_get_n_events    (GimpController *controller);
54 static const gchar * gimp_controller_mouse_get_event_name  (GimpController *controller,
55                                                             gint            event_id);
56 static const gchar * gimp_controller_mouse_get_event_blurb (GimpController *controller,
57                                                             gint            event_id);
58 
59 
60 G_DEFINE_TYPE (GimpControllerMouse, gimp_controller_mouse,
61                GIMP_TYPE_CONTROLLER)
62 
63 #define parent_class gimp_controller_mouse_parent_class
64 
65 
66 static MouseEvent mouse_events[] =
67 {
68   { 8, NULL, 0,
69     "8",
70     N_("Button 8") },
71   { 8, "<Shift>", 0,
72     "8-shift",
73     N_("Button 8") },
74   { 8, "<Primary>", 0,
75     "8-primary",
76     N_("Button 8") },
77   { 8, "<Alt>", 0,
78     "8-alt",
79     N_("Button 8") },
80   { 8, "<Shift><Primary>", 0,
81     "8-shift-primary",
82     N_("Button 8") },
83   { 8, "<Shift><Alt>", 0,
84     "8-shift-alt",
85     N_("Button 8") },
86   { 8, "<Primary><Alt>", 0,
87     "8-primary-alt",
88     N_("Button 8") },
89   { 8, "<Shift><Primary><Alt>", 0,
90     "8-shift-primary-alt",
91     N_("Button 8") },
92 
93   { 9, NULL, 0,
94     "9",
95     N_("Button 9") },
96   { 9, "<Shift>", 0,
97     "9-shift",
98     N_("Button 9") },
99   { 9, "<Primary>", 0,
100     "9-primary",
101     N_("Button 9") },
102   { 9, "<Alt>", 0,
103     "9-alt",
104     N_("Button 9") },
105   { 9, "<Shift><Primary>", 0,
106     "9-shift-primary",
107     N_("Button 9") },
108   { 9, "<Shift><Alt>", 0,
109     "9-shift-alt",
110     N_("Button 9") },
111   { 9, "<Primary><Alt>", 0,
112     "9-primary-alt",
113     N_("Button 9") },
114   { 9, "<Shift><Primary><Alt>", 0,
115     "9-shift-primary-alt",
116     N_("Button 9") },
117 
118   { 10, NULL, 0,
119     "10",
120     N_("Button 10") },
121   { 10, "<Shift>", 0,
122     "10-shift",
123     N_("Button 10") },
124   { 10, "<Primary>", 0,
125     "10-primary",
126     N_("Button 10") },
127   { 10, "<Alt>", 0,
128     "10-alt",
129     N_("Button 10") },
130   { 10, "<Shift><Primary>", 0,
131     "10-shift-primary",
132     N_("Button 10") },
133   { 10, "<Shift><Alt>", 0,
134     "10-shift-alt",
135     N_("Button 10") },
136   { 10, "<Primary><Alt>", 0,
137     "10-primary-alt",
138     N_("Button 10") },
139   { 10, "<Shift><Primary><Alt>", 0,
140     "10-shift-primary-alt",
141     N_("Button 10") },
142 
143   { 11, NULL, 0,
144     "11",
145     N_("Button 11") },
146   { 11, "<Shift>", 0,
147     "11-shift",
148     N_("Button 11") },
149   { 11, "<Primary>", 0,
150     "11-primary",
151     N_("Button 11") },
152   { 11, "<Alt>", 0,
153     "11-alt",
154     N_("Button 11") },
155   { 11, "<Shift><Primary>", 0,
156     "11-shift-primary",
157     N_("Button 11") },
158   { 11, "<Shift><Alt>", 0,
159     "11-shift-alt",
160     N_("Button 11") },
161   { 11, "<Primary><Alt>", 0,
162     "11-primary-alt",
163     N_("Button 11") },
164   { 11, "<Shift><Primary><Alt>", 0,
165     "11-shift-primary-alt",
166     N_("Button 11") },
167 
168   { 12, NULL, 0,
169     "12",
170     N_("Button 12") },
171   { 12, "<Shift>", 0,
172     "12-shift",
173     N_("Button 12") },
174   { 12, "<Primary>", 0,
175     "12-primary",
176     N_("Button 12") },
177   { 12, "<Alt>", 0,
178     "12-alt",
179     N_("Button 12") },
180   { 12, "<Shift><Primary>", 0,
181     "12-shift-primary",
182     N_("Button 12") },
183   { 12, "<Shift><Alt>", 0,
184     "12-shift-alt",
185     N_("Button 12") },
186   { 12, "<Primary><Alt>", 0,
187     "12-primary-alt",
188     N_("Button 12") },
189   { 12, "<Shift><Primary><Alt>", 0,
190     "12-shift-primary-alt",
191     N_("Button 12") },
192 };
193 
194 
195 static void
gimp_controller_mouse_class_init(GimpControllerMouseClass * klass)196 gimp_controller_mouse_class_init (GimpControllerMouseClass *klass)
197 {
198   GObjectClass        *object_class     = G_OBJECT_CLASS (klass);
199   GimpControllerClass *controller_class = GIMP_CONTROLLER_CLASS (klass);
200 
201   object_class->constructed         = gimp_controller_mouse_constructed;
202 
203   controller_class->name            = _("Mouse Buttons");
204   controller_class->help_id         = GIMP_HELP_CONTROLLER_MOUSE;
205   controller_class->icon_name       = GIMP_ICON_CONTROLLER_MOUSE;
206 
207   controller_class->get_n_events    = gimp_controller_mouse_get_n_events;
208   controller_class->get_event_name  = gimp_controller_mouse_get_event_name;
209   controller_class->get_event_blurb = gimp_controller_mouse_get_event_blurb;
210 }
211 
212 static void
gimp_controller_mouse_init(GimpControllerMouse * mouse)213 gimp_controller_mouse_init (GimpControllerMouse *mouse)
214 {
215   static gboolean event_names_initialized = FALSE;
216 
217   if (! event_names_initialized)
218     {
219       GdkKeymap *keymap = gdk_keymap_get_default ();
220       gint       i;
221 
222       for (i = 0; i < G_N_ELEMENTS (mouse_events); i++)
223         {
224           MouseEvent *mevent = &mouse_events[i];
225 
226           if (mevent->modifier_string)
227             {
228               gtk_accelerator_parse (mevent->modifier_string, NULL,
229                                      &mevent->modifiers);
230               gdk_keymap_map_virtual_modifiers (keymap, &mevent->modifiers);
231             }
232 
233           if (mevent->modifiers != 0)
234             {
235               mevent->blurb =
236                 g_strdup_printf ("%s (%s)", gettext (mevent->blurb),
237                                  gimp_get_mod_string (mevent->modifiers));
238             }
239         }
240 
241       event_names_initialized = TRUE;
242     }
243 }
244 
245 static void
gimp_controller_mouse_constructed(GObject * object)246 gimp_controller_mouse_constructed (GObject *object)
247 {
248   G_OBJECT_CLASS (parent_class)->constructed (object);
249 
250   g_object_set (object,
251                 "name",  _("Mouse Button Events"),
252                 "state", _("Ready"),
253                 NULL);
254 }
255 
256 static gint
gimp_controller_mouse_get_n_events(GimpController * controller)257 gimp_controller_mouse_get_n_events (GimpController *controller)
258 {
259   return G_N_ELEMENTS (mouse_events);
260 }
261 
262 static const gchar *
gimp_controller_mouse_get_event_name(GimpController * controller,gint event_id)263 gimp_controller_mouse_get_event_name (GimpController *controller,
264                                       gint            event_id)
265 {
266   if (event_id < 0 || event_id >= G_N_ELEMENTS (mouse_events))
267     return NULL;
268 
269   return mouse_events[event_id].name;
270 }
271 
272 static const gchar *
gimp_controller_mouse_get_event_blurb(GimpController * controller,gint event_id)273 gimp_controller_mouse_get_event_blurb (GimpController *controller,
274                                        gint            event_id)
275 {
276   if (event_id < 0 || event_id >= G_N_ELEMENTS (mouse_events))
277     return NULL;
278 
279   return mouse_events[event_id].blurb;
280 }
281 
282 gboolean
gimp_controller_mouse_button(GimpControllerMouse * mouse,const GdkEventButton * bevent)283 gimp_controller_mouse_button (GimpControllerMouse  *mouse,
284                               const GdkEventButton *bevent)
285 {
286   gint i;
287 
288   g_return_val_if_fail (GIMP_IS_CONTROLLER_MOUSE (mouse), FALSE);
289   g_return_val_if_fail (bevent != NULL, FALSE);
290 
291   /*  start with the last event because the last ones in the
292    *  up,down,left,right groups have the most keyboard modifiers
293    */
294   for (i = G_N_ELEMENTS (mouse_events) - 1; i >= 0; i--)
295     {
296       if (mouse_events[i].button == bevent->button &&
297           (mouse_events[i].modifiers & bevent->state) ==
298           mouse_events[i].modifiers)
299         {
300           GimpControllerEvent         controller_event;
301           GimpControllerEventTrigger *trigger;
302 
303           trigger = (GimpControllerEventTrigger *) &controller_event;
304 
305           trigger->type     = GIMP_CONTROLLER_EVENT_TRIGGER;
306           trigger->source   = GIMP_CONTROLLER (mouse);
307           trigger->event_id = i;
308 
309           return gimp_controller_event (GIMP_CONTROLLER (mouse),
310                                         &controller_event);
311         }
312     }
313 
314   return FALSE;
315 }
316