PageRenderTime 57ms CodeModel.GetById 28ms RepoModel.GetById 0ms app.codeStats 0ms

/xkbdata.c

https://github.com/ArneBab/arch-hurd-xkb-driver
C | 464 lines | 307 code | 83 blank | 74 comment | 40 complexity | e42068312238f77ace83d9f7e20e975c MD5 | raw file
  1. /* xkbdata.c -- Manage XKB datastructures.
  2. Copyright (C) 2003 Marco Gerards
  3. Written by Marco Gerards <marco@student.han.nl>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details. */
  12. /* Generate a key for the string S. XXX: The are many more effecient
  13. algoritms, this one should be replaced by one of those. */
  14. #include <stdlib.h>
  15. #include <string.h>
  16. #include <hurd/ihash.h>
  17. #include "xkb.h"
  18. static int
  19. name_hash (char *s)
  20. {
  21. int i = 0;
  22. while (*s)
  23. i += *(s++);
  24. return i;
  25. }
  26. /* A keyname with a keycode and realmodifier bound to it. */
  27. struct keyname
  28. {
  29. int keycode;
  30. int rmods;
  31. };
  32. static struct hurd_ihash kn_mapping;
  33. /* Initialize the keyname hashtable. */
  34. static void
  35. keyname_init ()
  36. {
  37. hurd_ihash_init (&kn_mapping, HURD_IHASH_NO_LOCP);
  38. debug_printf ("Kn_mapping init");
  39. /* XXX: error. */
  40. }
  41. static inline int
  42. keyname_hash(char *keyname)
  43. {
  44. char tmp[4] = { 0 };
  45. strncpy(tmp, keyname, sizeof tmp);
  46. return tmp[0] + (tmp[1] << 8) + (tmp[2] << 16) + (tmp[3] << 24);
  47. }
  48. /* Assign the name KEYNAME to the keycode KEYCODE. */
  49. error_t
  50. keyname_add (char *keyname, int keycode)
  51. {
  52. struct keyname *kn;
  53. int kn_int;
  54. kn = malloc (sizeof (struct keyname));
  55. if (!kn)
  56. return ENOMEM;
  57. /* XXX: 4 characters can be mapped into a int, it is safe to assume
  58. this will not be changed. */
  59. if (strlen (keyname) > 4)
  60. {
  61. debug_printf ("The keyname `%s' consist of more than 4 characters;"
  62. " 4 characters is the maximum.\n", keyname);
  63. /* XXX: Abort? */
  64. return 0;
  65. }
  66. kn->keycode = keycode;
  67. kn->rmods = 0;
  68. kn_int = keyname_hash(keyname);
  69. debug_printf ("add key %s(%d) hash: %d\n", keyname, keycode, kn_int);
  70. hurd_ihash_add (&kn_mapping, kn_int, kn);
  71. return 0;
  72. }
  73. /* Find the numberic representation of the keycode with the name
  74. KEYNAME. */
  75. int
  76. keyname_find (char *keyname)
  77. {
  78. struct keyname *kn;
  79. int kn_int;
  80. /* XXX: 4 characters can be mapped into a int, it is safe to assume
  81. this will not be changed. */
  82. if (strlen (keyname) > 4)
  83. {
  84. debug_printf ("The keyname `%s' consist of more than 4 characters;"
  85. " 4 characters is the maximum.\n", keyname);
  86. /* XXX: Abort? */
  87. return 0;
  88. }
  89. kn_int = keyname_hash(keyname);
  90. kn = hurd_ihash_find (&kn_mapping, kn_int);
  91. if (kn)
  92. return kn->keycode;
  93. /* int h = name_hash (keyname); */
  94. /* struct keyname *kn; */
  95. /* for (kn = knhash[KNHASH(h)]; kn; kn = kn->hnext) */
  96. /* { */
  97. /* if (strcmp (kn->keyname, keyname)) */
  98. /* continue; */
  99. /* return kn->keycode; */
  100. /* } */
  101. /* XXX: Is 0 an invalid keycode? */
  102. return 0;
  103. }
  104. /* Keytypes and keytype maps. */
  105. /* The dummy gets used when the original may not be overwritten. */
  106. static struct keytype dummy_keytype;
  107. #define KTHSZ 16
  108. #if ((KTHSZ&(KTHSZ-1)) == 0)
  109. #define KTHASH(ktttl) ((ktttl)&(KTHSZ-1))
  110. #else
  111. #define KTHASH(ktttl) (((unsigned)(kt))%KTHSZ)
  112. #endif
  113. /* All keytypes. */
  114. struct keytype *kthash[KTHSZ];
  115. /* Initialize the keytypes hashtable. */
  116. static void
  117. keytype_init ()
  118. {
  119. int n;
  120. for (n = 0; n < KTHSZ; n++)
  121. kthash[n] = 0;
  122. }
  123. /* Search the keytype with the name NAME. */
  124. struct keytype *
  125. keytype_find (char *name)
  126. {
  127. int nhash = name_hash (name);
  128. struct keytype *kt;
  129. for (kt = kthash[KTHASH(nhash)]; kt; kt = kt->hnext)
  130. if (!strcmp (name, kt->name))
  131. return kt;
  132. return NULL;
  133. }
  134. /* Remove the keytype KT. */
  135. void
  136. keytype_delete (struct keytype *kt)
  137. {
  138. struct typemap *map;
  139. *kt->prevp = kt->hnext;
  140. if (kt->hnext)
  141. kt->hnext->prevp = kt->prevp;
  142. map = kt->maps;
  143. while (map)
  144. {
  145. struct typemap *nextmap = map->next;
  146. free (map);
  147. map = nextmap;
  148. }
  149. }
  150. /* Create a new keytype with the name NAME. */
  151. error_t
  152. keytype_new (char *name, struct keytype **new_kt)
  153. {
  154. struct keytype *kt;
  155. struct keytype *ktlist;
  156. int nhash;
  157. nhash = name_hash (name);
  158. debug_printf ("New: %s\n", name);
  159. kt = keytype_find (name);
  160. if (kt)
  161. {
  162. /* If the merge mode is augement don't replace it. */
  163. if (merge_mode == augment)
  164. {
  165. *new_kt = &dummy_keytype;
  166. return 0;
  167. }
  168. else /* This keytype should replace the old one, remove the old one. */
  169. keytype_delete (kt);
  170. }
  171. ktlist = kthash[KTHASH(nhash)];
  172. kt = calloc (1, sizeof (struct keytype));
  173. if (kt == NULL)
  174. return ENOMEM;
  175. kt->hnext = ktlist;
  176. kt->name = strdup (name);
  177. kt->prevp = &kthash[KTHASH(nhash)];
  178. kt->maps = NULL;
  179. if (kthash[KTHASH(nhash)])
  180. kthash[KTHASH(nhash)]->prevp = &(kt->hnext);
  181. kthash[KTHASH(nhash)] = kt;
  182. *new_kt = kt;
  183. return 0;
  184. }
  185. /* Add a level (LEVEL) to modifiers (MODS) mapping to the current
  186. keytype. */
  187. error_t
  188. keytype_mapadd (struct keytype *kt, modmap_t mods, int level)
  189. {
  190. struct typemap *map;
  191. modmap_t nulmap = {0, 0};
  192. map = malloc (sizeof (struct typemap));
  193. if (!map)
  194. return ENOMEM;
  195. map->level = level;
  196. map->mods = mods;
  197. map->preserve = nulmap;
  198. /* By default modifiers shouldn't be preserved. */
  199. map->next = kt->maps;
  200. kt->maps = map;
  201. return 0;
  202. }
  203. /* For the current keytype the modifiers PRESERVE should be preserved
  204. when the modifiers MODS are pressed. */
  205. error_t
  206. keytype_preserve_add (struct keytype *kt, modmap_t mods, modmap_t preserve)
  207. {
  208. error_t err;
  209. struct typemap *map;
  210. map = kt->maps;
  211. while (map)
  212. {
  213. if (mods.rmods == map->mods.rmods && mods.vmods == map->mods.vmods)
  214. {
  215. map->preserve = preserve;
  216. return 0;
  217. }
  218. map = map->next;
  219. }
  220. /* No map has been found, add the default map. */
  221. err = keytype_mapadd (kt, mods, 0);
  222. if (err)
  223. return err;
  224. keytype_preserve_add (kt, mods, preserve);
  225. return 0;
  226. }
  227. /* Interpretations. */
  228. struct xkb_interpret *last_interp;
  229. struct xkb_interpret default_interpretation;
  230. /* Add a new interpretation. */
  231. error_t
  232. interpret_new (xkb_interpret_t **new_interpret, symbol ks)
  233. {
  234. struct xkb_interpret *new_interp;
  235. new_interp = malloc (sizeof (struct xkb_interpret));
  236. if (!new_interp)
  237. return ENOMEM;
  238. memcpy (new_interp, &default_interpretation, sizeof (struct xkb_interpret));
  239. new_interp->symbol = ks;
  240. if (ks)
  241. {
  242. new_interp->next = interpretations;
  243. interpretations = new_interp;
  244. if (!last_interp)
  245. last_interp = new_interp;
  246. }
  247. else
  248. {
  249. if (last_interp)
  250. last_interp->next = new_interp;
  251. last_interp = new_interp;
  252. if (!interpretations)
  253. interpretations = new_interp;
  254. }
  255. *new_interpret = new_interp;
  256. return 0;
  257. }
  258. /* XXX: Dead code!? */
  259. /* Virtual modifiers name to number mapping. */
  260. /* Last number assigned to a virtual modifier. */
  261. static int lastvmod = 0;
  262. /* One virtual modifiername -> vmod number mapping. */
  263. struct vmodname
  264. {
  265. char *name;
  266. struct vmodname *next;
  267. };
  268. /* A list of virtualmodifier names and its numberic representation. */
  269. static struct vmodname *vmodnamel;
  270. /* Get the number assigned to the virtualmodifier with the name
  271. VMODNAME. */
  272. int
  273. vmod_find (char *vmodname)
  274. {
  275. int i = 0;
  276. struct vmodname *vmn = vmodnamel;
  277. while (vmn)
  278. {
  279. if (!strcmp (vmn->name, vmodname))
  280. return (lastvmod - i);
  281. vmn = vmn->next;
  282. i++;
  283. }
  284. return 0;
  285. }
  286. /* Give the virtualmodifier VMODNAME a number and add it to the
  287. hashtable. */
  288. error_t
  289. vmod_add (char *vmodname)
  290. {
  291. struct vmodname *vmn;
  292. if (vmod_find (vmodname))
  293. return 0;
  294. vmn = malloc (sizeof (struct vmodname));
  295. if (vmn == NULL)
  296. return ENOMEM;
  297. vmn->name = vmodname;
  298. vmn->next = vmodnamel;
  299. vmodnamel = vmn;
  300. lastvmod++;
  301. if (lastvmod > 16)
  302. debug_printf("warning: only sixteen virtual modifiers are supported, %s will not be functional.\n", vmodname);
  303. return 0;
  304. }
  305. /* XXX: Use this, no pointers. */
  306. struct ksrm
  307. {
  308. symbol ks;
  309. int rmods;
  310. };
  311. static struct hurd_ihash ksrm_mapping;
  312. /* Initialize the list for keysyms to realmodifiers mappings. */
  313. void
  314. ksrm_init ()
  315. {
  316. hurd_ihash_init (&ksrm_mapping, HURD_IHASH_NO_LOCP);
  317. debug_printf ("KSRM MAP IHASH CREATED \n");
  318. }
  319. /* Add keysym to realmodifier mapping. */
  320. error_t
  321. ksrm_add (symbol ks, int rmod)
  322. {
  323. hurd_ihash_add (&ksrm_mapping, ks, (void *) rmod);
  324. return 0;
  325. }
  326. /* Apply the rkms (realmods to keysyms) table to all keysyms. */
  327. void
  328. ksrm_apply (void)
  329. {
  330. keycode_t kc;
  331. for (kc = 0; kc < max_keys; kc++)
  332. {
  333. int group;
  334. for (group = 0; group < 4; group++)
  335. {
  336. int cursym;
  337. for (cursym = 0; cursym < keys[kc].groups[group].width; cursym++)
  338. {
  339. symbol ks = keys[kc].groups[group].symbols[cursym];
  340. int rmods = (int) hurd_ihash_find (&ksrm_mapping, ks);
  341. if (rmods)
  342. {
  343. keys[kc].mods.rmods = rmods;
  344. }
  345. }
  346. }
  347. }
  348. }
  349. /* void */
  350. /* indicator_new (xkb_indicator_t **, */
  351. /* Keycode to realmodifier mapping. */
  352. /* Set the current rmod for the key with keyname KEYNAME. */
  353. /* XXX: It shouldn't be applied immediatly because the key can be
  354. replaced. */
  355. void
  356. set_rmod_keycode (char *keyname, int rmod)
  357. {
  358. keycode_t kc = keyname_find (keyname);
  359. keys[kc].mods.rmods = rmod;
  360. debug_printf ("%s (kc %d) rmod: %d\n", keyname, kc, rmod);
  361. }
  362. /* Initialize XKB data structures. */
  363. error_t
  364. xkb_data_init (void)
  365. {
  366. keyname_init ();
  367. keytype_init ();
  368. ksrm_init ();
  369. return 0;
  370. }