diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:29:01 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 16:29:01 +0000 |
commit | 35a96bde514a8897f6f0fcc41c5833bf63df2e2a (patch) | |
tree | 657d15a03cc46bd099fc2c6546a7a4ad43815d9f /src/ui/tool/event-utils.cpp | |
parent | Initial commit. (diff) | |
download | inkscape-35a96bde514a8897f6f0fcc41c5833bf63df2e2a.tar.xz inkscape-35a96bde514a8897f6f0fcc41c5833bf63df2e2a.zip |
Adding upstream version 1.0.2.upstream/1.0.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/ui/tool/event-utils.cpp')
-rw-r--r-- | src/ui/tool/event-utils.cpp | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/ui/tool/event-utils.cpp b/src/ui/tool/event-utils.cpp new file mode 100644 index 0000000..33a196d --- /dev/null +++ b/src/ui/tool/event-utils.cpp @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * Collection of shorthands to deal with GDK events. + */ +/* Authors: + * Krzysztof KosiĆski <tweenk.pl@gmail.com> + * + * Copyright (C) 2009 Authors + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include <cstring> +#include <gdk/gdk.h> +#include <gdk/gdkkeysyms.h> +#include <gdkmm/display.h> +#include "display/sp-canvas.h" +#include "ui/tool/event-utils.h" + +namespace Inkscape { +namespace UI { + + +guint shortcut_key(GdkEventKey const &event) +{ + guint shortcut_key = 0; + gdk_keymap_translate_keyboard_state( + Gdk::Display::get_default()->get_keymap(), + event.hardware_keycode, + (GdkModifierType) event.state, + 0 /*event->key.group*/, + &shortcut_key, nullptr, nullptr, nullptr); + return shortcut_key; +} + +unsigned combine_key_events(guint keyval, gint mask) +{ + GdkEvent *event_next; + gint i = 0; + + event_next = gdk_event_get(); + // while the next event is also a key notify with the same keyval and mask, + while (event_next && (event_next->type == GDK_KEY_PRESS || event_next->type == GDK_KEY_RELEASE) + && event_next->key.keyval == keyval + && (!mask || event_next->key.state & mask)) { + if (event_next->type == GDK_KEY_PRESS) + i ++; + // kill it + gdk_event_free(event_next); + // get next + event_next = gdk_event_get(); + } + // otherwise, put it back onto the queue + if (event_next) gdk_event_put(event_next); + + return i; +} + +unsigned combine_motion_events(SPCanvas *canvas, GdkEventMotion &event, gint mask) +{ + if (canvas == nullptr) { + return false; + } + GdkEvent *event_next; + gint i = 0; + event.x -= canvas->_x0; + event.y -= canvas->_y0; + + event_next = gdk_event_get(); + // while the next event is also a motion notify + while (event_next && (event_next->type == GDK_MOTION_NOTIFY) + && (!mask || event_next->motion.state & mask)) + { + if (event_next->motion.device == event.device) { + GdkEventMotion &next = event_next->motion; + event.send_event = next.send_event; + event.time = next.time; + event.x = next.x; + event.y = next.y; + event.state = next.state; + event.is_hint = next.is_hint; + event.x_root = next.x_root; + event.y_root = next.y_root; + if (event.axes && next.axes) { + memcpy(event.axes, next.axes, gdk_device_get_n_axes(event.device)); + } + } + + // kill it + gdk_event_free(event_next); + event_next = gdk_event_get(); + i++; + } + // otherwise, put it back onto the queue + if (event_next) { + gdk_event_put(event_next); + } + event.x += canvas->_x0; + event.y += canvas->_y0; + + return i; +} + +/** Returns the modifier state valid after this event. Use this when you process events + * that change the modifier state. Currently handles only Shift, Ctrl, Alt. */ +unsigned state_after_event(GdkEvent *event) +{ + unsigned state = 0; + switch (event->type) { + case GDK_KEY_PRESS: + state = event->key.state; + switch(shortcut_key(event->key)) { + case GDK_KEY_Shift_L: + case GDK_KEY_Shift_R: + state |= GDK_SHIFT_MASK; + break; + case GDK_KEY_Control_L: + case GDK_KEY_Control_R: + state |= GDK_CONTROL_MASK; + break; + case GDK_KEY_Alt_L: + case GDK_KEY_Alt_R: + state |= GDK_MOD1_MASK; + break; + default: break; + } + break; + case GDK_KEY_RELEASE: + state = event->key.state; + switch(shortcut_key(event->key)) { + case GDK_KEY_Shift_L: + case GDK_KEY_Shift_R: + state &= ~GDK_SHIFT_MASK; + break; + case GDK_KEY_Control_L: + case GDK_KEY_Control_R: + state &= ~GDK_CONTROL_MASK; + break; + case GDK_KEY_Alt_L: + case GDK_KEY_Alt_R: + state &= ~GDK_MOD1_MASK; + break; + default: break; + } + break; + default: break; + } + return state; +} + +} // namespace UI +} // namespace Inkscape + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 : |