Code

Super duper mega (fun!) commit: replaced encoding=utf-8 with fileencoding=utf-8 in...
[inkscape.git] / src / ui / tool / event-utils.cpp
1 /** @file
2  * Collection of shorthands to deal with GDK events.
3  */
4 /* Authors:
5  *   Krzysztof KosiƄski <tweenk.pl@gmail.com>
6  *
7  * Copyright (C) 2009 Authors
8  * Released under GNU GPL, read the file 'COPYING' for more information
9  */
11 #include <cstring>
12 #include <gdk/gdk.h>
13 #include <gdk/gdkkeysyms.h>
14 #include "display/sp-canvas.h"
15 #include "ui/tool/event-utils.h"
17 namespace Inkscape {
18 namespace UI {
21 guint shortcut_key(GdkEventKey const &event)
22 {
23     guint shortcut_key = 0;
24     gdk_keymap_translate_keyboard_state(
25             gdk_keymap_get_for_display(gdk_display_get_default()),
26             event.hardware_keycode,
27             (GdkModifierType) event.state,
28             0   /*event->key.group*/,
29             &shortcut_key, NULL, NULL, NULL);
30     return shortcut_key;
31 }
33 unsigned combine_key_events(guint keyval, gint mask)
34 {
35     GdkEvent *event_next;
36     gint i = 0;
38     event_next = gdk_event_get();
39     // while the next event is also a key notify with the same keyval and mask,
40     while (event_next && (event_next->type == GDK_KEY_PRESS || event_next->type == GDK_KEY_RELEASE)
41            && event_next->key.keyval == keyval
42            && (!mask || event_next->key.state & mask)) {
43         if (event_next->type == GDK_KEY_PRESS)
44             i ++;
45         // kill it
46         gdk_event_free(event_next);
47         // get next
48         event_next = gdk_event_get();
49     }
50     // otherwise, put it back onto the queue
51     if (event_next) gdk_event_put(event_next);
53     return i;
54 }
56 unsigned combine_motion_events(SPCanvas *canvas, GdkEventMotion &event, gint mask)
57 {
58     GdkEvent *event_next;
59     gint i = 0;
60     event.x -= canvas->x0;
61     event.y -= canvas->y0;
63     event_next = gdk_event_get();
64     // while the next event is also a motion notify
65     while (event_next && event_next->type == GDK_MOTION_NOTIFY
66             && (!mask || event_next->motion.state & mask))
67     {
68         if (event_next->motion.device == event.device) {
69             GdkEventMotion &next = event_next->motion;
70             event.send_event = next.send_event;
71             event.time = next.time;
72             event.x = next.x;
73             event.y = next.y;
74             event.state = next.state;
75             event.is_hint = next.is_hint;
76             event.x_root = next.x_root;
77             event.y_root = next.y_root;
78             if (event.axes && next.axes) {
79                 memcpy(event.axes, next.axes, event.device->num_axes);
80             }
81         }
83         // kill it
84         gdk_event_free(event_next);
85         event_next = gdk_event_get();
86         i++;
87     }
88     // otherwise, put it back onto the queue
89     if (event_next)
90         gdk_event_put(event_next);
91     event.x += canvas->x0;
92     event.y += canvas->y0;
94     return i;
95 }
97 /** Returns the modifier state valid after this event. Use this when you process events
98  * that change the modifier state. Currently handles only Shift, Ctrl, Alt. */
99 unsigned state_after_event(GdkEvent *event)
101     unsigned state = 0;
102     switch (event->type) {
103     case GDK_KEY_PRESS:
104         state = event->key.state;
105         switch(shortcut_key(event->key)) {
106         case GDK_Shift_L:
107         case GDK_Shift_R:
108             state |= GDK_SHIFT_MASK;
109             break;
110         case GDK_Control_L:
111         case GDK_Control_R:
112             state |= GDK_CONTROL_MASK;
113             break;
114         case GDK_Alt_L:
115         case GDK_Alt_R:
116             state |= GDK_MOD1_MASK;
117             break;
118         default: break;
119         }
120         break;
121     case GDK_KEY_RELEASE:
122         state = event->key.state;
123         switch(shortcut_key(event->key)) {
124         case GDK_Shift_L:
125         case GDK_Shift_R:
126             state &= ~GDK_SHIFT_MASK;
127             break;
128         case GDK_Control_L:
129         case GDK_Control_R:
130             state &= ~GDK_CONTROL_MASK;
131             break;
132         case GDK_Alt_L:
133         case GDK_Alt_R:
134             state &= ~GDK_MOD1_MASK;
135             break;
136         default: break;
137         }
138         break;
139     default: break;
140     }
141     return state;
144 } // namespace UI
145 } // namespace Inkscape
147 /*
148   Local Variables:
149   mode:c++
150   c-file-style:"stroustrup"
151   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
152   indent-tabs-mode:nil
153   fill-column:99
154   End:
155 */
156 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :