diff --git a/clutter/clutter/clutter-keyval.c b/clutter/clutter/clutter-keyval.c new file mode 100644 index 000000000..12ea0d9d5 --- /dev/null +++ b/clutter/clutter/clutter-keyval.c @@ -0,0 +1,215 @@ +/* + * 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 + * + * The code is a modified version of the GDK implementation + */ + +#include +#include + +#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; +} \ No newline at end of file diff --git a/clutter/clutter/clutter-keyval.h b/clutter/clutter/clutter-keyval.h new file mode 100644 index 000000000..5f9b4ee62 --- /dev/null +++ b/clutter/clutter/clutter-keyval.h @@ -0,0 +1,44 @@ +/* + * 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 + * + * The code is a modified version of the GDK implementation + */ +#ifndef __CLUTTER_KEYVAL_H__ +#define __CLUTTER_KEYVAL_H__ + +#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) +#error "Only can be included directly." +#endif + +#include + +G_BEGIN_DECLS + +CLUTTER_EXPORT +void clutter_keyval_convert_case (unsigned int symbol, + unsigned int *lower, + unsigned int *upper); + +CLUTTER_EXPORT +char * clutter_keyval_name (unsigned int keyval); + +G_END_DECLS + +#endif /* __CLUTTER_KEYVAL_H__ */ diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h index 3ba51c16b..6295ae7b4 100644 --- a/clutter/clutter/clutter.h +++ b/clutter/clutter/clutter.h @@ -76,6 +76,7 @@ #include "clutter-keyframe-transition.h" #include "clutter-keymap.h" #include "clutter-keysyms.h" +#include "clutter-keyval.h" #include "clutter-layout-manager.h" #include "clutter-layout-meta.h" #include "clutter-macros.h" diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index 854e4918f..88bccdcb1 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -50,6 +50,8 @@ clutter_headers = [ 'clutter-keyframe-transition.h', 'clutter-keymap.h', 'clutter-keysyms.h', + 'clutter-keyval.c', + 'clutter-keyval.h', 'clutter-layout-manager.h', 'clutter-layout-meta.h', 'clutter-macros.h',