627 lines
23 KiB
C
627 lines
23 KiB
C
/* PIKA - Photo and Image Kooker Application
|
|
* a rebranding of The GNU Image Manipulation Program (created with heckimp)
|
|
* A derived work which may be trivial. However, any changes may be (C)2023 by Aldercone Studio
|
|
*
|
|
* Original copyright, applying to most contents (license remains unchanged):
|
|
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
|
|
*
|
|
* pikamodifiersmanager.c
|
|
* Copyright (C) 2022 Jehan
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include "libpikabase/pikabase.h"
|
|
#include "libpikaconfig/pikaconfig.h"
|
|
|
|
#include "display-types.h"
|
|
|
|
#include "widgets/pikawidgets-utils.h"
|
|
|
|
#include "pikamodifiersmanager.h"
|
|
|
|
#include "pika-intl.h"
|
|
|
|
enum
|
|
{
|
|
MODIFIERS_MANAGER_MAPPING,
|
|
MODIFIERS_MANAGER_MODIFIERS,
|
|
MODIFIERS_MANAGER_MOD_ACTION,
|
|
};
|
|
|
|
typedef struct
|
|
{
|
|
GdkModifierType modifiers;
|
|
PikaModifierAction mod_action;
|
|
gchar *action_desc;
|
|
} PikaModifierMapping;
|
|
|
|
struct _PikaModifiersManagerPrivate
|
|
{
|
|
GHashTable *actions;
|
|
GList *buttons;
|
|
};
|
|
|
|
static void pika_modifiers_manager_config_iface_init (PikaConfigInterface *iface);
|
|
static void pika_modifiers_manager_finalize (GObject *object);
|
|
static gboolean pika_modifiers_manager_serialize (PikaConfig *config,
|
|
PikaConfigWriter *writer,
|
|
gpointer data);
|
|
static gboolean pika_modifiers_manager_deserialize (PikaConfig *config,
|
|
GScanner *scanner,
|
|
gint nest_level,
|
|
gpointer data);
|
|
|
|
static void pika_modifiers_manager_free_mapping (PikaModifierMapping *mapping);
|
|
|
|
static void pika_modifiers_manager_get_keys (GdkDevice *device,
|
|
guint button,
|
|
GdkModifierType modifiers,
|
|
gchar **actions_key,
|
|
gchar **buttons_key);
|
|
static void pika_modifiers_manager_initialize (PikaModifiersManager *manager,
|
|
GdkDevice *device,
|
|
guint button);
|
|
|
|
|
|
G_DEFINE_TYPE_WITH_CODE (PikaModifiersManager, pika_modifiers_manager, G_TYPE_OBJECT,
|
|
G_ADD_PRIVATE (PikaModifiersManager)
|
|
G_IMPLEMENT_INTERFACE (PIKA_TYPE_CONFIG,
|
|
pika_modifiers_manager_config_iface_init))
|
|
|
|
#define parent_class pika_modifiers_manager_parent_class
|
|
|
|
|
|
static void
|
|
pika_modifiers_manager_class_init (PikaModifiersManagerClass *klass)
|
|
{
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->finalize = pika_modifiers_manager_finalize;
|
|
}
|
|
|
|
static void
|
|
pika_modifiers_manager_init (PikaModifiersManager *manager)
|
|
{
|
|
manager->p = pika_modifiers_manager_get_instance_private (manager);
|
|
|
|
manager->p->actions = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
|
|
(GDestroyNotify) pika_modifiers_manager_free_mapping);
|
|
}
|
|
|
|
static void
|
|
pika_modifiers_manager_config_iface_init (PikaConfigInterface *iface)
|
|
{
|
|
iface->serialize = pika_modifiers_manager_serialize;
|
|
iface->deserialize = pika_modifiers_manager_deserialize;
|
|
}
|
|
|
|
static void
|
|
pika_modifiers_manager_finalize (GObject *object)
|
|
{
|
|
PikaModifiersManager *manager = PIKA_MODIFIERS_MANAGER (object);
|
|
|
|
G_OBJECT_CLASS (parent_class)->finalize (object);
|
|
|
|
g_hash_table_unref (manager->p->actions);
|
|
g_list_free_full (manager->p->buttons, g_free);
|
|
}
|
|
|
|
static gboolean
|
|
pika_modifiers_manager_serialize (PikaConfig *config,
|
|
PikaConfigWriter *writer,
|
|
gpointer data)
|
|
{
|
|
PikaModifiersManager *manager = PIKA_MODIFIERS_MANAGER (config);
|
|
GEnumClass *enum_class;
|
|
GList *keys;
|
|
GList *iter;
|
|
|
|
enum_class = g_type_class_ref (PIKA_TYPE_MODIFIER_ACTION);
|
|
keys = g_hash_table_get_keys (manager->p->actions);
|
|
|
|
for (iter = keys; iter; iter = iter->next)
|
|
{
|
|
const gchar *button = iter->data;
|
|
PikaModifierMapping *mapping;
|
|
GEnumValue *enum_value;
|
|
|
|
pika_config_writer_open (writer, "mapping");
|
|
pika_config_writer_string (writer, button);
|
|
|
|
mapping = g_hash_table_lookup (manager->p->actions, button);
|
|
|
|
pika_config_writer_open (writer, "modifiers");
|
|
pika_config_writer_printf (writer, "%d", mapping->modifiers);
|
|
pika_config_writer_close (writer);
|
|
|
|
enum_value = g_enum_get_value (enum_class, GPOINTER_TO_INT (mapping->mod_action));
|
|
pika_config_writer_open (writer, "mod-action");
|
|
pika_config_writer_identifier (writer, enum_value->value_nick);
|
|
if (mapping->mod_action == PIKA_MODIFIER_ACTION_ACTION)
|
|
pika_config_writer_string (writer, mapping->action_desc);
|
|
pika_config_writer_close (writer);
|
|
|
|
pika_config_writer_close (writer);
|
|
}
|
|
|
|
g_list_free (keys);
|
|
g_type_class_unref (enum_class);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
pika_modifiers_manager_deserialize (PikaConfig *config,
|
|
GScanner *scanner,
|
|
gint nest_level,
|
|
gpointer data)
|
|
{
|
|
PikaModifiersManager *manager = PIKA_MODIFIERS_MANAGER (config);
|
|
GEnumClass *enum_class;
|
|
GTokenType token;
|
|
guint scope_id;
|
|
guint old_scope_id;
|
|
gchar *actions_key = NULL;
|
|
GdkModifierType modifiers = 0;
|
|
|
|
scope_id = g_type_qname (G_TYPE_FROM_INSTANCE (config));
|
|
old_scope_id = g_scanner_set_scope (scanner, scope_id);
|
|
enum_class = g_type_class_ref (PIKA_TYPE_MODIFIER_ACTION);
|
|
|
|
g_scanner_scope_add_symbol (scanner, scope_id, "mapping",
|
|
GINT_TO_POINTER (MODIFIERS_MANAGER_MAPPING));
|
|
g_scanner_scope_add_symbol (scanner, scope_id, "modifiers",
|
|
GINT_TO_POINTER (MODIFIERS_MANAGER_MODIFIERS));
|
|
g_scanner_scope_add_symbol (scanner, scope_id, "mod-action",
|
|
GINT_TO_POINTER (MODIFIERS_MANAGER_MOD_ACTION));
|
|
|
|
token = G_TOKEN_LEFT_PAREN;
|
|
|
|
while (g_scanner_peek_next_token (scanner) == token)
|
|
{
|
|
token = g_scanner_get_next_token (scanner);
|
|
|
|
switch (token)
|
|
{
|
|
case G_TOKEN_LEFT_PAREN:
|
|
token = G_TOKEN_SYMBOL;
|
|
break;
|
|
|
|
case G_TOKEN_SYMBOL:
|
|
switch (GPOINTER_TO_INT (scanner->value.v_symbol))
|
|
{
|
|
case MODIFIERS_MANAGER_MAPPING:
|
|
token = G_TOKEN_LEFT_PAREN;
|
|
if (! pika_scanner_parse_string (scanner, &actions_key))
|
|
goto error;
|
|
break;
|
|
|
|
case MODIFIERS_MANAGER_MOD_ACTION:
|
|
{
|
|
PikaModifierMapping *mapping;
|
|
GEnumValue *enum_value;
|
|
|
|
token = G_TOKEN_IDENTIFIER;
|
|
if (g_scanner_peek_next_token (scanner) != token)
|
|
goto error;
|
|
|
|
g_scanner_get_next_token (scanner);
|
|
|
|
enum_value = g_enum_get_value_by_nick (enum_class,
|
|
scanner->value.v_identifier);
|
|
|
|
if (! enum_value)
|
|
enum_value = g_enum_get_value_by_name (enum_class,
|
|
scanner->value.v_identifier);
|
|
|
|
if (! enum_value)
|
|
{
|
|
g_scanner_error (scanner,
|
|
_("invalid value '%s' for contextual action"),
|
|
scanner->value.v_identifier);
|
|
return G_TOKEN_NONE;
|
|
}
|
|
|
|
if (g_hash_table_lookup (manager->p->actions, actions_key))
|
|
{
|
|
/* This should not happen. But let's avoid breaking
|
|
* the whole parsing for a duplicate. Just output to
|
|
* stderr to track any problematic modifiersrc
|
|
* creation.
|
|
*/
|
|
g_printerr ("%s: ignoring duplicate action %s for mapping %s\n",
|
|
G_STRFUNC, scanner->value.v_identifier, actions_key);
|
|
g_clear_pointer (&actions_key, g_free);
|
|
}
|
|
else
|
|
{
|
|
gchar *suffix;
|
|
gchar *action_desc = NULL;
|
|
|
|
if (enum_value->value == PIKA_MODIFIER_ACTION_ACTION)
|
|
{
|
|
if (! pika_scanner_parse_string (scanner, &action_desc))
|
|
{
|
|
g_printerr ("%s: missing action description for mapping %s\n",
|
|
G_STRFUNC, actions_key);
|
|
goto error;
|
|
}
|
|
}
|
|
|
|
suffix = g_strdup_printf ("-%d", modifiers);
|
|
|
|
if (g_str_has_suffix (actions_key, suffix))
|
|
{
|
|
gchar *buttons_key = g_strndup (actions_key,
|
|
strlen (actions_key) - strlen (suffix));
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = modifiers;
|
|
mapping->mod_action = enum_value->value;
|
|
mapping->action_desc = action_desc;
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
|
|
if (g_list_find_custom (manager->p->buttons, buttons_key, (GCompareFunc) g_strcmp0))
|
|
g_free (buttons_key);
|
|
else
|
|
manager->p->buttons = g_list_prepend (manager->p->buttons, buttons_key);
|
|
}
|
|
else
|
|
{
|
|
g_printerr ("%s: ignoring mapping %s with invalid modifiers %d\n",
|
|
G_STRFUNC, actions_key, modifiers);
|
|
g_clear_pointer (&actions_key, g_free);
|
|
}
|
|
|
|
g_free (suffix);
|
|
}
|
|
|
|
/* Closing parentheses twice. */
|
|
token = G_TOKEN_RIGHT_PAREN;
|
|
if (g_scanner_peek_next_token (scanner) != token)
|
|
goto error;
|
|
|
|
g_scanner_get_next_token (scanner);
|
|
}
|
|
break;
|
|
|
|
case MODIFIERS_MANAGER_MODIFIERS:
|
|
token = G_TOKEN_RIGHT_PAREN;
|
|
if (! pika_scanner_parse_int (scanner, (int *) &modifiers))
|
|
goto error;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case G_TOKEN_RIGHT_PAREN:
|
|
token = G_TOKEN_LEFT_PAREN;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
error:
|
|
|
|
g_scanner_scope_remove_symbol (scanner, scope_id, "mapping");
|
|
g_scanner_scope_remove_symbol (scanner, scope_id, "modifiers");
|
|
g_scanner_scope_remove_symbol (scanner, scope_id, "mod-action");
|
|
|
|
g_scanner_set_scope (scanner, old_scope_id);
|
|
g_type_class_unref (enum_class);
|
|
|
|
return G_TOKEN_LEFT_PAREN;
|
|
}
|
|
|
|
|
|
/* public functions */
|
|
|
|
PikaModifiersManager *
|
|
pika_modifiers_manager_new (void)
|
|
{
|
|
return g_object_new (PIKA_TYPE_MODIFIERS_MANAGER, NULL);
|
|
}
|
|
|
|
PikaModifierAction
|
|
pika_modifiers_manager_get_action (PikaModifiersManager *manager,
|
|
GdkDevice *device,
|
|
guint button,
|
|
GdkModifierType state,
|
|
const gchar **action_desc)
|
|
{
|
|
gchar *actions_key = NULL;
|
|
gchar *buttons_key = NULL;
|
|
GdkModifierType mod_state;
|
|
PikaModifierAction retval = PIKA_MODIFIER_ACTION_NONE;
|
|
|
|
g_return_val_if_fail (PIKA_IS_MODIFIERS_MANAGER (manager), PIKA_MODIFIER_ACTION_NONE);
|
|
g_return_val_if_fail (GDK_IS_DEVICE (device), PIKA_MODIFIER_ACTION_NONE);
|
|
g_return_val_if_fail (action_desc != NULL && *action_desc == NULL, PIKA_MODIFIER_ACTION_NONE);
|
|
|
|
mod_state = state & pika_get_all_modifiers_mask ();
|
|
|
|
pika_modifiers_manager_get_keys (device, button, mod_state,
|
|
&actions_key, &buttons_key);
|
|
|
|
if (g_list_find_custom (manager->p->buttons, buttons_key, (GCompareFunc) g_strcmp0))
|
|
{
|
|
PikaModifierMapping *mapping;
|
|
|
|
mapping = g_hash_table_lookup (manager->p->actions, actions_key);
|
|
|
|
if (mapping == NULL)
|
|
retval = PIKA_MODIFIER_ACTION_NONE;
|
|
else
|
|
retval = mapping->mod_action;
|
|
|
|
if (retval == PIKA_MODIFIER_ACTION_ACTION)
|
|
*action_desc = mapping->action_desc;
|
|
}
|
|
else if (button == 2)
|
|
{
|
|
if (mod_state == pika_get_extend_selection_mask ())
|
|
retval = PIKA_MODIFIER_ACTION_ROTATING;
|
|
else if (mod_state == (pika_get_extend_selection_mask () | GDK_CONTROL_MASK))
|
|
retval = PIKA_MODIFIER_ACTION_STEP_ROTATING;
|
|
else if (mod_state == pika_get_toggle_behavior_mask ())
|
|
retval = PIKA_MODIFIER_ACTION_ZOOMING;
|
|
else if (mod_state == GDK_MOD1_MASK)
|
|
retval = PIKA_MODIFIER_ACTION_LAYER_PICKING;
|
|
else if (mod_state == 0)
|
|
retval = PIKA_MODIFIER_ACTION_PANNING;
|
|
}
|
|
else if (button == 3)
|
|
{
|
|
if (mod_state == GDK_MOD1_MASK)
|
|
retval = PIKA_MODIFIER_ACTION_BRUSH_PIXEL_SIZE;
|
|
else if (mod_state == 0)
|
|
retval = PIKA_MODIFIER_ACTION_MENU;
|
|
}
|
|
|
|
g_free (actions_key);
|
|
g_free (buttons_key);
|
|
|
|
return retval;
|
|
}
|
|
|
|
GList *
|
|
pika_modifiers_manager_get_modifiers (PikaModifiersManager *manager,
|
|
GdkDevice *device,
|
|
guint button)
|
|
{
|
|
gchar *buttons_key = NULL;
|
|
GList *modifiers = NULL;
|
|
GList *action_keys;
|
|
GList *iter;
|
|
gchar *action_prefix;
|
|
|
|
pika_modifiers_manager_initialize (manager, device, button);
|
|
|
|
pika_modifiers_manager_get_keys (device, button, 0, NULL,
|
|
&buttons_key);
|
|
action_prefix = g_strdup_printf ("%s-", buttons_key);
|
|
g_free (buttons_key);
|
|
|
|
action_keys = g_hash_table_get_keys (manager->p->actions);
|
|
for (iter = action_keys; iter; iter = iter->next)
|
|
{
|
|
if (g_str_has_prefix (iter->data, action_prefix))
|
|
{
|
|
PikaModifierMapping *mapping;
|
|
|
|
mapping = g_hash_table_lookup (manager->p->actions, iter->data);
|
|
|
|
/* TODO: the modifiers list should be sorted to ensure
|
|
* consistency.
|
|
*/
|
|
modifiers = g_list_prepend (modifiers, GINT_TO_POINTER (mapping->modifiers));
|
|
}
|
|
}
|
|
|
|
g_free (action_prefix);
|
|
g_list_free (action_keys);
|
|
|
|
return modifiers;
|
|
}
|
|
|
|
void
|
|
pika_modifiers_manager_set (PikaModifiersManager *manager,
|
|
GdkDevice *device,
|
|
guint button,
|
|
GdkModifierType modifiers,
|
|
PikaModifierAction action,
|
|
const gchar *action_desc)
|
|
{
|
|
gchar *actions_key = NULL;
|
|
gchar *buttons_key = NULL;
|
|
|
|
g_return_if_fail (PIKA_IS_MODIFIERS_MANAGER (manager));
|
|
g_return_if_fail (GDK_IS_DEVICE (device));
|
|
|
|
pika_modifiers_manager_get_keys (device, button, modifiers,
|
|
&actions_key, &buttons_key);
|
|
g_free (buttons_key);
|
|
|
|
pika_modifiers_manager_initialize (manager, device, button);
|
|
|
|
if (action == PIKA_MODIFIER_ACTION_NONE ||
|
|
(action == PIKA_MODIFIER_ACTION_ACTION && action_desc == NULL))
|
|
{
|
|
g_hash_table_remove (manager->p->actions, actions_key);
|
|
g_free (actions_key);
|
|
}
|
|
else
|
|
{
|
|
PikaModifierMapping *mapping;
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = modifiers;
|
|
mapping->mod_action = action;
|
|
mapping->action_desc = action_desc ? g_strdup (action_desc) : NULL;
|
|
g_hash_table_insert (manager->p->actions, actions_key,
|
|
mapping);
|
|
}
|
|
}
|
|
|
|
void
|
|
pika_modifiers_manager_remove (PikaModifiersManager *manager,
|
|
GdkDevice *device,
|
|
guint button,
|
|
GdkModifierType modifiers)
|
|
{
|
|
pika_modifiers_manager_set (manager, device, button, modifiers,
|
|
PIKA_MODIFIER_ACTION_NONE, NULL);
|
|
}
|
|
|
|
void
|
|
pika_modifiers_manager_clear (PikaModifiersManager *manager)
|
|
{
|
|
g_hash_table_remove_all (manager->p->actions);
|
|
g_list_free_full (manager->p->buttons, g_free);
|
|
manager->p->buttons = NULL;
|
|
}
|
|
|
|
/* Private functions */
|
|
|
|
static void
|
|
pika_modifiers_manager_free_mapping (PikaModifierMapping *mapping)
|
|
{
|
|
g_free (mapping->action_desc);
|
|
g_slice_free (PikaModifierMapping, mapping);
|
|
}
|
|
|
|
static void
|
|
pika_modifiers_manager_get_keys (GdkDevice *device,
|
|
guint button,
|
|
GdkModifierType modifiers,
|
|
gchar **actions_key,
|
|
gchar **buttons_key)
|
|
{
|
|
const gchar *vendor_id;
|
|
const gchar *product_id;
|
|
|
|
g_return_if_fail (GDK_IS_DEVICE (device) || device == NULL);
|
|
|
|
vendor_id = device ? gdk_device_get_vendor_id (device) : NULL;
|
|
product_id = device ? gdk_device_get_product_id (device) : NULL;
|
|
modifiers = modifiers & pika_get_all_modifiers_mask ();
|
|
|
|
if (actions_key)
|
|
*actions_key = g_strdup_printf ("%s:%s-%d-%d",
|
|
vendor_id ? vendor_id : "(no-vendor-id)",
|
|
product_id ? product_id : "(no-product-id)",
|
|
button, modifiers);
|
|
if (buttons_key)
|
|
*buttons_key = g_strdup_printf ("%s:%s-%d",
|
|
vendor_id ? vendor_id : "(no-vendor-id)",
|
|
product_id ? product_id : "(no-product-id)",
|
|
button);
|
|
}
|
|
|
|
static void
|
|
pika_modifiers_manager_initialize (PikaModifiersManager *manager,
|
|
GdkDevice *device,
|
|
guint button)
|
|
{
|
|
gchar *buttons_key = NULL;
|
|
|
|
g_return_if_fail (PIKA_IS_MODIFIERS_MANAGER (manager));
|
|
g_return_if_fail (GDK_IS_DEVICE (device));
|
|
|
|
pika_modifiers_manager_get_keys (device, button, 0,
|
|
NULL, &buttons_key);
|
|
|
|
/* Add the button to buttons whether or not we insert or remove an
|
|
* action. It mostly mean that we "touched" the settings for a given
|
|
* device/button. So it's a per-button initialized flag.
|
|
*/
|
|
if (g_list_find_custom (manager->p->buttons, buttons_key, (GCompareFunc) g_strcmp0))
|
|
{
|
|
g_free (buttons_key);
|
|
}
|
|
else
|
|
{
|
|
gchar *actions_key = NULL;
|
|
PikaModifierMapping *mapping;
|
|
|
|
manager->p->buttons = g_list_prepend (manager->p->buttons, buttons_key);
|
|
if (button == 2)
|
|
{
|
|
/* The default mapping for second (middle) button which had no explicit configuration. */
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = GDK_MOD1_MASK;
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_LAYER_PICKING;
|
|
pika_modifiers_manager_get_keys (device, 2, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = pika_get_extend_selection_mask () | GDK_CONTROL_MASK;
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_STEP_ROTATING;
|
|
pika_modifiers_manager_get_keys (device, 2, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = pika_get_extend_selection_mask ();
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_ROTATING;
|
|
pika_modifiers_manager_get_keys (device, 2, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = pika_get_toggle_behavior_mask ();
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_ZOOMING;
|
|
pika_modifiers_manager_get_keys (device, 2, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = 0;
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_PANNING;
|
|
pika_modifiers_manager_get_keys (device, 2, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
}
|
|
else if (button == 3)
|
|
{
|
|
/* The default mapping for third button which had no explicit configuration. */
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = GDK_MOD1_MASK;
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_BRUSH_PIXEL_SIZE;
|
|
pika_modifiers_manager_get_keys (device, 3, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
|
|
mapping = g_slice_new (PikaModifierMapping);
|
|
mapping->modifiers = 0;
|
|
mapping->mod_action = PIKA_MODIFIER_ACTION_MENU;
|
|
pika_modifiers_manager_get_keys (device, 3, mapping->modifiers,
|
|
&actions_key, NULL);
|
|
g_hash_table_insert (manager->p->actions, actions_key, mapping);
|
|
}
|
|
}
|
|
}
|