mutter/clutter/clutter/clutter-keyval.c
Bilal Elmoussaoui 6aeb9eef4e clutter: Add keyval helpers
Infrastructure for adding meta_accelerator_name

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2407>
2022-12-22 15:13:54 +01:00

215 lines
8.6 KiB
C

/*
* Copyright (C) 2021 Red Hat
*
* 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 2 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, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* Author: Bilal Elmoussaoui <belmous@redhat.com>
*
* The code is a modified version of the GDK implementation
*/
#include <glib.h>
#include <glib/gprintf.h>
#include "clutter-keyval.h"
#include "clutter-event.h"
#include "clutter-keysyms.h"
#include "clutter-keyname-table.h"
#define CLUTTER_NUM_KEYS G_N_ELEMENTS (clutter_keys_by_keyval)
/**
* clutter_keyval_convert_case:
* @symbol: a keyval.
* @lower: (out): return location of the lowercase version of @symbol.
* @upper: (out): return location of the uppercase version of @symbol.
*/
void
clutter_keyval_convert_case (unsigned int symbol,
unsigned int *lower,
unsigned int *upper)
{
unsigned int xlower, xupper;
xlower = symbol;
xupper = symbol;
/* Check for directly encoded 24-bit UCS characters: */
if ((symbol & 0xff000000) == 0x01000000)
{
if (lower)
*lower = clutter_unicode_to_keysym (g_unichar_tolower (symbol & 0x00ffffff));
if (upper)
*upper = clutter_unicode_to_keysym (g_unichar_toupper (symbol & 0x00ffffff));
return;
}
switch (symbol >> 8)
{
case 0: /* Latin 1 */
if ((symbol >= CLUTTER_KEY_A) && (symbol <= CLUTTER_KEY_Z))
xlower += (CLUTTER_KEY_a - CLUTTER_KEY_A);
else if ((symbol >= CLUTTER_KEY_a) && (symbol <= CLUTTER_KEY_z))
xupper -= (CLUTTER_KEY_a - CLUTTER_KEY_A);
else if ((symbol >= CLUTTER_KEY_Agrave) && (symbol <= CLUTTER_KEY_Odiaeresis))
xlower += (CLUTTER_KEY_agrave - CLUTTER_KEY_Agrave);
else if ((symbol >= CLUTTER_KEY_agrave) && (symbol <= CLUTTER_KEY_odiaeresis))
xupper -= (CLUTTER_KEY_agrave - CLUTTER_KEY_Agrave);
else if ((symbol >= CLUTTER_KEY_Ooblique) && (symbol <= CLUTTER_KEY_Thorn))
xlower += (CLUTTER_KEY_oslash - CLUTTER_KEY_Ooblique);
else if ((symbol >= CLUTTER_KEY_oslash) && (symbol <= CLUTTER_KEY_thorn))
xupper -= (CLUTTER_KEY_oslash - CLUTTER_KEY_Ooblique);
break;
case 1: /* Latin 2 */
/* Assume the KeySym is a legal value (ignore discontinuities) */
if (symbol == CLUTTER_KEY_Aogonek)
xlower = CLUTTER_KEY_aogonek;
else if (symbol >= CLUTTER_KEY_Lstroke && symbol <= CLUTTER_KEY_Sacute)
xlower += (CLUTTER_KEY_lstroke - CLUTTER_KEY_Lstroke);
else if (symbol >= CLUTTER_KEY_Scaron && symbol <= CLUTTER_KEY_Zacute)
xlower += (CLUTTER_KEY_scaron - CLUTTER_KEY_Scaron);
else if (symbol >= CLUTTER_KEY_Zcaron && symbol <= CLUTTER_KEY_Zabovedot)
xlower += (CLUTTER_KEY_zcaron - CLUTTER_KEY_Zcaron);
else if (symbol == CLUTTER_KEY_aogonek)
xupper = CLUTTER_KEY_Aogonek;
else if (symbol >= CLUTTER_KEY_lstroke && symbol <= CLUTTER_KEY_sacute)
xupper -= (CLUTTER_KEY_lstroke - CLUTTER_KEY_Lstroke);
else if (symbol >= CLUTTER_KEY_scaron && symbol <= CLUTTER_KEY_zacute)
xupper -= (CLUTTER_KEY_scaron - CLUTTER_KEY_Scaron);
else if (symbol >= CLUTTER_KEY_zcaron && symbol <= CLUTTER_KEY_zabovedot)
xupper -= (CLUTTER_KEY_zcaron - CLUTTER_KEY_Zcaron);
else if (symbol >= CLUTTER_KEY_Racute && symbol <= CLUTTER_KEY_Tcedilla)
xlower += (CLUTTER_KEY_racute - CLUTTER_KEY_Racute);
else if (symbol >= CLUTTER_KEY_racute && symbol <= CLUTTER_KEY_tcedilla)
xupper -= (CLUTTER_KEY_racute - CLUTTER_KEY_Racute);
break;
case 2: /* Latin 3 */
/* Assume the KeySym is a legal value (ignore discontinuities) */
if (symbol >= CLUTTER_KEY_Hstroke && symbol <= CLUTTER_KEY_Hcircumflex)
xlower += (CLUTTER_KEY_hstroke - CLUTTER_KEY_Hstroke);
else if (symbol >= CLUTTER_KEY_Gbreve && symbol <= CLUTTER_KEY_Jcircumflex)
xlower += (CLUTTER_KEY_gbreve - CLUTTER_KEY_Gbreve);
else if (symbol >= CLUTTER_KEY_hstroke && symbol <= CLUTTER_KEY_hcircumflex)
xupper -= (CLUTTER_KEY_hstroke - CLUTTER_KEY_Hstroke);
else if (symbol >= CLUTTER_KEY_gbreve && symbol <= CLUTTER_KEY_jcircumflex)
xupper -= (CLUTTER_KEY_gbreve - CLUTTER_KEY_Gbreve);
else if (symbol >= CLUTTER_KEY_Cabovedot && symbol <= CLUTTER_KEY_Scircumflex)
xlower += (CLUTTER_KEY_cabovedot - CLUTTER_KEY_Cabovedot);
else if (symbol >= CLUTTER_KEY_cabovedot && symbol <= CLUTTER_KEY_scircumflex)
xupper -= (CLUTTER_KEY_cabovedot - CLUTTER_KEY_Cabovedot);
break;
case 3: /* Latin 4 */
/* Assume the KeySym is a legal value (ignore discontinuities) */
if (symbol >= CLUTTER_KEY_Rcedilla && symbol <= CLUTTER_KEY_Tslash)
xlower += (CLUTTER_KEY_rcedilla - CLUTTER_KEY_Rcedilla);
else if (symbol >= CLUTTER_KEY_rcedilla && symbol <= CLUTTER_KEY_tslash)
xupper -= (CLUTTER_KEY_rcedilla - CLUTTER_KEY_Rcedilla);
else if (symbol == CLUTTER_KEY_ENG)
xlower = CLUTTER_KEY_eng;
else if (symbol == CLUTTER_KEY_eng)
xupper = CLUTTER_KEY_ENG;
else if (symbol >= CLUTTER_KEY_Amacron && symbol <= CLUTTER_KEY_Umacron)
xlower += (CLUTTER_KEY_amacron - CLUTTER_KEY_Amacron);
else if (symbol >= CLUTTER_KEY_amacron && symbol <= CLUTTER_KEY_umacron)
xupper -= (CLUTTER_KEY_amacron - CLUTTER_KEY_Amacron);
break;
case 6: /* Cyrillic */
/* Assume the KeySym is a legal value (ignore discontinuities) */
if (symbol >= CLUTTER_KEY_Serbian_DJE && symbol <= CLUTTER_KEY_Serbian_DZE)
xlower -= (CLUTTER_KEY_Serbian_DJE - CLUTTER_KEY_Serbian_dje);
else if (symbol >= CLUTTER_KEY_Serbian_dje && symbol <= CLUTTER_KEY_Serbian_dze)
xupper += (CLUTTER_KEY_Serbian_DJE - CLUTTER_KEY_Serbian_dje);
else if (symbol >= CLUTTER_KEY_Cyrillic_YU && symbol <= CLUTTER_KEY_Cyrillic_HARDSIGN)
xlower -= (CLUTTER_KEY_Cyrillic_YU - CLUTTER_KEY_Cyrillic_yu);
else if (symbol >= CLUTTER_KEY_Cyrillic_yu && symbol <= CLUTTER_KEY_Cyrillic_hardsign)
xupper += (CLUTTER_KEY_Cyrillic_YU - CLUTTER_KEY_Cyrillic_yu);
break;
case 7: /* Greek */
/* Assume the KeySym is a legal value (ignore discontinuities) */
if (symbol >= CLUTTER_KEY_Greek_ALPHAaccent && symbol <= CLUTTER_KEY_Greek_OMEGAaccent)
xlower += (CLUTTER_KEY_Greek_alphaaccent - CLUTTER_KEY_Greek_ALPHAaccent);
else if (symbol >= CLUTTER_KEY_Greek_alphaaccent && symbol <= CLUTTER_KEY_Greek_omegaaccent &&
symbol != CLUTTER_KEY_Greek_iotaaccentdieresis &&
symbol != CLUTTER_KEY_Greek_upsilonaccentdieresis)
xupper -= (CLUTTER_KEY_Greek_alphaaccent - CLUTTER_KEY_Greek_ALPHAaccent);
else if (symbol >= CLUTTER_KEY_Greek_ALPHA && symbol <= CLUTTER_KEY_Greek_OMEGA)
xlower += (CLUTTER_KEY_Greek_alpha - CLUTTER_KEY_Greek_ALPHA);
else if (symbol == CLUTTER_KEY_Greek_finalsmallsigma)
xupper = CLUTTER_KEY_Greek_SIGMA;
else if (symbol >= CLUTTER_KEY_Greek_alpha && symbol <= CLUTTER_KEY_Greek_omega)
xupper -= (CLUTTER_KEY_Greek_alpha - CLUTTER_KEY_Greek_ALPHA);
break;
default:
break;
}
if (lower)
*lower = xlower;
if (upper)
*upper = xupper;
}
static int
clutter_keys_keyval_compare (const void *pkey, const void *pbase)
{
return (*(int *) pkey) - ((clutter_key *) pbase)->keyval;
}
/**
* clutter_keyval_name:
* @keyval: A key value.
*
* Returns: (nullable): The corresponding symbolic name.
*/
char *
clutter_keyval_name (unsigned int keyval)
{
static char buf[100];
clutter_key *found;
/* Check for directly encoded 24-bit UCS characters: */
if ((keyval & 0xff000000) == 0x01000000)
{
g_sprintf (buf, "U+%.04X", (keyval & 0x00ffffff));
return buf;
}
found = bsearch (&keyval, clutter_keys_by_keyval,
CLUTTER_NUM_KEYS, sizeof (clutter_key),
clutter_keys_keyval_compare);
if (found != NULL)
{
while ((found > clutter_keys_by_keyval) &&
((found - 1)->keyval == keyval))
found--;
return (char *) (keynames + found->offset);
}
else if (keyval != 0)
{
g_sprintf (buf, "%#x", keyval);
return buf;
}
return NULL;
}