keyseq.c 104 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901
  1. /*
  2. * Copyright © 2012 Ran Benita <ran234@gmail.com>
  3. * SPDX-License-Identifier: MIT
  4. */
  5. #include "config.h"
  6. #include "test-config.h"
  7. #include "xkbcommon/xkbcommon-keysyms.h"
  8. #include "xkbcommon/xkbcommon.h"
  9. #include "evdev-scancodes.h"
  10. #include "test.h"
  11. #include "keymap.h"
  12. #include "utils.h"
  13. enum fake_keys {
  14. KEY_LVL3 = 84
  15. };
  16. static const enum xkb_keymap_format keymap_formats[] = {
  17. XKB_KEYMAP_FORMAT_TEXT_V1,
  18. XKB_KEYMAP_FORMAT_TEXT_V2,
  19. };
  20. static inline xkb_keysym_t
  21. get_keysym(struct xkb_keymap *keymap, xkb_keysym_t v1, xkb_keysym_t v2)
  22. {
  23. return (keymap->format == XKB_KEYMAP_FORMAT_TEXT_V1) ? v1 : v2;
  24. }
  25. static void
  26. test_group_lock(struct xkb_context *ctx)
  27. {
  28. struct xkb_keymap *keymap;
  29. /*
  30. * Group lock on press (all formats)
  31. * Implicit lockOnRelease=false (XKB spec)
  32. */
  33. for (unsigned int f = 0; f < ARRAY_SIZE(keymap_formats); f++) {
  34. keymap = test_compile_rules(ctx, keymap_formats[f],
  35. "evdev", "pc105",
  36. "us,de", "",
  37. "grp:alt_shift_toggle");
  38. assert(keymap);
  39. #define test_group_lock_on_press(keymap) assert( \
  40. test_key_seq((keymap), \
  41. KEY_Y, BOTH, XKB_KEY_y, NEXT, \
  42. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, \
  43. KEY_LEFTSHIFT, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  44. /* Group change on press */ \
  45. KEY_Y, BOTH, XKB_KEY_z, NEXT, \
  46. KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  47. /* Group change on press */ \
  48. KEY_Y, BOTH, XKB_KEY_y, NEXT, \
  49. KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  50. KEY_Y, BOTH, XKB_KEY_y, NEXT, \
  51. KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH)\
  52. )
  53. test_group_lock_on_press(keymap);
  54. xkb_keymap_unref(keymap);
  55. }
  56. /*
  57. * Group lock on press for format V2
  58. * Explicit lockOnRelease=false (XKB spec)
  59. */
  60. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  61. "evdev", "pc105",
  62. "us,de", "",
  63. "grp:alt_shift_toggle,grp:lockOnPress");
  64. test_group_lock_on_press(keymap);
  65. xkb_keymap_unref(keymap);
  66. #undef test_group_lock_on_press
  67. /*
  68. * Group lock on release for format V2
  69. * Explicit lockOnRelease=true (XKB extension)
  70. */
  71. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  72. "evdev", "pc105",
  73. "us,de", "",
  74. "grp:alt_shift_toggle,grp:lockOnRelease");
  75. #define test_group_lock_on_release(keymap) assert( \
  76. test_key_seq((keymap), \
  77. KEY_Y, BOTH, XKB_KEY_y, NEXT, \
  78. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, \
  79. KEY_LEFTSHIFT, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  80. /* Group lock on release */ \
  81. KEY_Y, BOTH, XKB_KEY_z, NEXT, \
  82. KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  83. /* Key not released, no group change */ \
  84. KEY_Y, BOTH, XKB_KEY_z, NEXT, \
  85. KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  86. /* Group lock cancelled by intermediate key press */\
  87. KEY_Y, BOTH, XKB_KEY_z, NEXT, \
  88. KEY_Y, DOWN, XKB_KEY_z, NEXT, \
  89. KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  90. /* Group lock not cancelled by intermediate key release */\
  91. KEY_Y, UP, XKB_KEY_z, NEXT, \
  92. KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  93. /* Group lock on release */ \
  94. KEY_Y, BOTH, XKB_KEY_y, NEXT, \
  95. KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH)\
  96. )
  97. test_group_lock_on_release(keymap);
  98. xkb_keymap_unref(keymap);
  99. #undef test_group_lock_on_release
  100. }
  101. static void
  102. test_group_latch(struct xkb_context *ctx)
  103. {
  104. /* Absolute group, no lock */
  105. for (unsigned int f = 0; f < ARRAY_SIZE(keymap_formats); f++) {
  106. fprintf(stderr, "=== %s, format %u ===\n", __func__, keymap_formats[f]);
  107. struct xkb_keymap *keymap = test_compile_rules(
  108. ctx, keymap_formats[f], "evdev", "pc104",
  109. "us,il,ru,de", ",,phonetic,neo",
  110. "grp:menu_latch_group2,grp:sclk_toggle,grp:lctrl_rctrl_switch");
  111. assert(keymap);
  112. /* Set only */
  113. #define test_set_only(keymap_) \
  114. assert(test_key_seq(keymap_, \
  115. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  116. KEY_E, BOTH, XKB_KEY_e, NEXT, \
  117. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  118. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  119. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  120. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  121. /* Lock the second group */ \
  122. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  123. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  124. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  125. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  126. /* Event if the latch group is absolute, it sums with \
  127. * the locked group (see spec) */ \
  128. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  129. KEY_E, BOTH, XKB_KEY_Cyrillic_ie, NEXT, \
  130. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  131. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  132. KEY_E, BOTH, XKB_KEY_hebrew_qoph, FINISH))
  133. test_set_only(keymap);
  134. /* Latch only */
  135. #define test_latch_only(keymap_) \
  136. assert(test_key_seq(keymap_, \
  137. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  138. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  139. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  140. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  141. /* Empty level breaks latches */ \
  142. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  143. KEY_YEN, BOTH, XKB_KEY_NoSymbol, NEXT, \
  144. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  145. /* Unknown key does not break latches */ \
  146. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  147. UINT32_MAX, BOTH, XKB_KEY_NoSymbol, NEXT, \
  148. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  149. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  150. /* Lock the second group */ \
  151. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  152. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  153. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  154. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  155. /* Event if the latch group is absolute, it sums with \
  156. * the locked group (see spec) */ \
  157. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  158. KEY_H, BOTH, XKB_KEY_hebrew_yod, FINISH))
  159. test_latch_only(keymap);
  160. /* Latch not broken by modifier */
  161. #define test_latch_not_broken_by_modifier(keymap_) \
  162. assert(test_key_seq(keymap_, \
  163. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  164. /* Sequential */ \
  165. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  166. KEY_LEFTALT, BOTH, XKB_KEY_Alt_L, NEXT, \
  167. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  168. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  169. /* Simultaneous */ \
  170. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  171. KEY_LEFTALT, BOTH, XKB_KEY_Alt_L, NEXT, \
  172. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  173. KEY_H, BOTH, get_keysym(keymap, XKB_KEY_h, XKB_KEY_hebrew_yod), NEXT, \
  174. /* Simultaneous */ \
  175. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, \
  176. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  177. KEY_LEFTALT, UP, XKB_KEY_Alt_L, NEXT, \
  178. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  179. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  180. /* Simultaneous */ \
  181. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, \
  182. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  183. KEY_LEFTALT, UP, XKB_KEY_Alt_L, NEXT, \
  184. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  185. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  186. KEY_H, BOTH, XKB_KEY_h, FINISH))
  187. test_latch_not_broken_by_modifier(keymap);
  188. /* Simulatenous group actions */
  189. #define test_simultaneous_group_latches(keymap_) \
  190. assert(test_key_seq(keymap_, \
  191. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  192. /* Sequential */ \
  193. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  194. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  195. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  196. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  197. KEY_LEFTCTRL, BOTH, XKB_KEY_ISO_First_Group, NEXT, \
  198. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  199. /* Simultaneous */ \
  200. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  201. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  202. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  203. KEY_H, BOTH, get_keysym(keymap, XKB_KEY_hebrew_yod, XKB_KEY_Cyrillic_ha), NEXT, \
  204. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  205. KEY_LEFTCTRL, BOTH, XKB_KEY_ISO_First_Group, NEXT, \
  206. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  207. /* Simultaneous */ \
  208. KEY_SCROLLLOCK, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  209. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  210. KEY_SCROLLLOCK, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  211. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  212. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  213. KEY_LEFTCTRL, BOTH, XKB_KEY_ISO_First_Group, NEXT, \
  214. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  215. /* Simultaneous */ \
  216. KEY_SCROLLLOCK, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  217. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  218. KEY_SCROLLLOCK, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  219. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  220. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  221. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  222. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  223. KEY_LEFTCTRL, BOTH, XKB_KEY_ISO_First_Group, NEXT, \
  224. KEY_H, BOTH, XKB_KEY_h, FINISH))
  225. test_simultaneous_group_latches(keymap);
  226. /* No lock */
  227. #define test_no_latch_to_lock(keymap_) \
  228. assert(test_key_seq(keymap_, \
  229. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  230. /* No latch-to-lock */ \
  231. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  232. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  233. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  234. KEY_E, BOTH, XKB_KEY_e, NEXT, \
  235. /* Lock the second group */ \
  236. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  237. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  238. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  239. /* No latch-to-lock */ \
  240. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  241. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  242. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  243. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  244. /* Lock the third group */ \
  245. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  246. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  247. KEY_E, BOTH, XKB_KEY_Cyrillic_ie, NEXT, \
  248. /* No latch-to-lock */ \
  249. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  250. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  251. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  252. KEY_E, BOTH, XKB_KEY_Cyrillic_ie, FINISH))
  253. test_no_latch_to_lock(keymap);
  254. xkb_keymap_unref(keymap);
  255. /* Absolute group, latch-to-lock */
  256. keymap = test_compile_rules(
  257. ctx, keymap_formats[f], "evdev", "pc104",
  258. "us,il,ru,de", ",,phonetic,neo",
  259. "grp:menu_latch_group2_lock,grp:sclk_toggle,grp:lctrl_rctrl_switch");
  260. assert(keymap);
  261. test_set_only(keymap);
  262. test_latch_only(keymap);
  263. test_latch_not_broken_by_modifier(keymap);
  264. test_simultaneous_group_latches(keymap);
  265. /* Lock */
  266. assert(test_key_seq(keymap,
  267. KEY_H, BOTH, XKB_KEY_h, NEXT,
  268. /* Lock the second group via latch-to-lock */
  269. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  270. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  271. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  272. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT,
  273. /* Lock the third group via usual lock */
  274. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  275. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT,
  276. KEY_E, BOTH, XKB_KEY_Cyrillic_ie, NEXT,
  277. /* Lock the second group via latch-to-lock */
  278. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  279. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  280. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  281. KEY_E, BOTH, XKB_KEY_hebrew_qoph, FINISH));
  282. xkb_keymap_unref(keymap);
  283. /* Relative group (positive), no lock */
  284. keymap = test_compile_rules(
  285. ctx, keymap_formats[f], "evdev", "pc104",
  286. "us,il,ru,de", ",,phonetic,neo",
  287. "grp:menu_latch,grp:sclk_toggle,grp:lctrl_rctrl_switch");
  288. assert(keymap);
  289. test_set_only(keymap);
  290. test_latch_only(keymap);
  291. test_latch_not_broken_by_modifier(keymap);
  292. test_simultaneous_group_latches(keymap);
  293. test_no_latch_to_lock(keymap);
  294. xkb_keymap_unref(keymap);
  295. /* Relative group (positive), latch-to-lock */
  296. keymap = test_compile_rules(
  297. ctx, keymap_formats[f], "evdev", "pc104",
  298. "us,il,ru,de", ",,phonetic,neo",
  299. "grp:menu_latch_lock,grp:sclk_toggle,grp:lctrl_rctrl_switch");
  300. assert(keymap);
  301. test_set_only(keymap);
  302. test_latch_only(keymap);
  303. test_latch_not_broken_by_modifier(keymap);
  304. test_simultaneous_group_latches(keymap);
  305. /* Lock */
  306. assert(test_key_seq(keymap,
  307. KEY_H, BOTH, XKB_KEY_h, NEXT,
  308. /* Lock the second group via latch-to-lock */
  309. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  310. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  311. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  312. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT,
  313. /* Lock the third group via usual lock */
  314. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  315. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT,
  316. KEY_E, BOTH, XKB_KEY_Cyrillic_ie, NEXT,
  317. /* Lock the fourth group via latch-to-lock */
  318. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  319. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  320. KEY_H, BOTH, XKB_KEY_s, NEXT,
  321. KEY_E, BOTH, XKB_KEY_l, FINISH));
  322. xkb_keymap_unref(keymap);
  323. #undef test_set_only
  324. #undef test_latch_only
  325. #undef test_latch_not_broken_by_modifier
  326. #undef test_simultaneous_group_latches
  327. /* Relative group (negative), no lock */
  328. keymap = test_compile_rules(
  329. ctx, keymap_formats[f], "evdev", "pc104",
  330. "us,il,ru,de", ",,phonetic,neo",
  331. "grp:menu_latch_negative,grp:sclk_toggle,grp:lctrl_rctrl_switch");
  332. assert(keymap);
  333. /* Set only */
  334. #define test_set_only(keymap_) \
  335. assert(test_key_seq(keymap_, \
  336. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  337. KEY_E, BOTH, XKB_KEY_e, NEXT, \
  338. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  339. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  340. KEY_E, BOTH, XKB_KEY_l, NEXT, \
  341. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  342. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  343. /* Lock the second group */ \
  344. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  345. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  346. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  347. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  348. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  349. KEY_E, BOTH, XKB_KEY_e, NEXT, \
  350. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  351. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  352. KEY_E, BOTH, XKB_KEY_hebrew_qoph, FINISH))
  353. test_set_only(keymap);
  354. /* Latch only */
  355. #define test_latch_only(keymap_) \
  356. assert(test_key_seq(keymap_, \
  357. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  358. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  359. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  360. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  361. /* Empty level breaks latches */ \
  362. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  363. KEY_YEN, BOTH, XKB_KEY_NoSymbol, NEXT, \
  364. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  365. /* Unknown key does not break latches */ \
  366. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  367. UINT32_MAX, BOTH, XKB_KEY_NoSymbol, NEXT, \
  368. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  369. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  370. /* Lock the second group */ \
  371. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  372. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  373. KEY_E, BOTH, XKB_KEY_hebrew_qoph, NEXT, \
  374. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  375. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  376. KEY_H, BOTH, XKB_KEY_hebrew_yod, FINISH))
  377. test_latch_only(keymap);
  378. /* Latch not broken by modifier */
  379. #define test_latch_not_broken_by_modifier(keymap_) \
  380. assert(test_key_seq(keymap_, \
  381. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  382. /* Sequential */ \
  383. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  384. KEY_LEFTALT, BOTH, XKB_KEY_Alt_L, NEXT, \
  385. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  386. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  387. /* Simultaneous */ \
  388. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  389. KEY_LEFTALT, BOTH, XKB_KEY_Alt_L, NEXT, \
  390. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  391. KEY_H, BOTH, get_keysym(keymap, XKB_KEY_h, XKB_KEY_s), NEXT,\
  392. /* Simultaneous */ \
  393. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, \
  394. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  395. KEY_LEFTALT, UP, XKB_KEY_Alt_L, NEXT, \
  396. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  397. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  398. /* Simultaneous */ \
  399. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT, \
  400. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  401. KEY_LEFTALT, UP, XKB_KEY_Alt_L, NEXT, \
  402. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  403. KEY_H, BOTH, XKB_KEY_s, NEXT, \
  404. KEY_H, BOTH, XKB_KEY_h, FINISH))
  405. test_latch_not_broken_by_modifier(keymap);
  406. /* Simulatenous group actions */
  407. #define test_simultaneous_group_latches(keymap_) \
  408. assert(test_key_seq(keymap_, \
  409. KEY_H, BOTH, XKB_KEY_h, NEXT, \
  410. KEY_RIGHTCTRL, BOTH, XKB_KEY_ISO_Last_Group, NEXT, \
  411. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  412. /* Sequential */ \
  413. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  414. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  415. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  416. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  417. KEY_RIGHTCTRL, BOTH, XKB_KEY_ISO_Last_Group, NEXT, \
  418. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  419. /* Simultaneous */ \
  420. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  421. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT, \
  422. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  423. KEY_H, BOTH, get_keysym(keymap, XKB_KEY_Cyrillic_ha, XKB_KEY_hebrew_yod), NEXT,\
  424. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  425. KEY_RIGHTCTRL, BOTH, XKB_KEY_ISO_Last_Group, NEXT, \
  426. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  427. /* Simultaneous */ \
  428. KEY_SCROLLLOCK, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  429. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT, \
  430. KEY_SCROLLLOCK, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  431. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  432. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  433. KEY_RIGHTCTRL, BOTH, XKB_KEY_ISO_Last_Group, NEXT, \
  434. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  435. /* Simultaneous */ \
  436. KEY_SCROLLLOCK, DOWN, XKB_KEY_ISO_Next_Group, NEXT, \
  437. KEY_COMPOSE, DOWN, XKB_KEY_ISO_Group_Latch, NEXT, \
  438. KEY_SCROLLLOCK, UP, XKB_KEY_ISO_Next_Group, NEXT, \
  439. KEY_COMPOSE, UP, XKB_KEY_ISO_Group_Latch, NEXT, \
  440. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT, \
  441. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  442. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT, \
  443. KEY_RIGHTCTRL, BOTH, XKB_KEY_ISO_Last_Group, NEXT, \
  444. KEY_H, BOTH, XKB_KEY_hebrew_yod, FINISH))
  445. test_simultaneous_group_latches(keymap);
  446. test_no_latch_to_lock(keymap);
  447. xkb_keymap_unref(keymap);
  448. /* Relative group (negative), no lock */
  449. keymap = test_compile_rules(
  450. ctx, keymap_formats[f], "evdev", "pc104",
  451. "us,il,ru,de", ",,phonetic,neo",
  452. "grp:menu_latch_negative_lock,grp:sclk_toggle,grp:lctrl_rctrl_switch");
  453. assert(keymap);
  454. test_set_only(keymap);
  455. test_latch_only(keymap);
  456. test_latch_not_broken_by_modifier(keymap);
  457. test_simultaneous_group_latches(keymap);
  458. /* Lock */
  459. assert(test_key_seq(keymap,
  460. KEY_H, BOTH, XKB_KEY_h, NEXT,
  461. /* Lock the fourth group via latch-to-lock */
  462. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  463. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  464. KEY_H, BOTH, XKB_KEY_s, NEXT,
  465. KEY_E, BOTH, XKB_KEY_l, NEXT,
  466. /* Lock the third group via usual lock */
  467. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  468. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  469. KEY_SCROLLLOCK, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  470. KEY_H, BOTH, XKB_KEY_Cyrillic_ha, NEXT,
  471. KEY_E, BOTH, XKB_KEY_Cyrillic_ie, NEXT,
  472. /* Lock the second group via latch-to-lock */
  473. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  474. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Group_Latch, NEXT,
  475. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  476. KEY_E, BOTH, XKB_KEY_hebrew_qoph, FINISH));
  477. xkb_keymap_unref(keymap);
  478. #undef test_set_only
  479. #undef test_latch_only
  480. #undef test_latch_not_broken_by_modifier
  481. #undef test_simultaneous_group_latches
  482. #undef test_no_latch_to_lock
  483. }
  484. }
  485. static void
  486. test_mod_set(struct xkb_context *ctx)
  487. {
  488. struct xkb_keymap *keymap;
  489. /* Shift break caps: unlockOnPress=false */
  490. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  491. "evdev", "pc105", "us", "",
  492. "shift:breaks_caps");
  493. assert(test_key_seq(keymap,
  494. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  495. KEY_A, BOTH, XKB_KEY_A, NEXT,
  496. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  497. KEY_A, BOTH, XKB_KEY_a, NEXT,
  498. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  499. /* Caps still locked: key was operated before Shift release */
  500. KEY_A, BOTH, XKB_KEY_A, FINISH
  501. ));
  502. assert(keymap);
  503. xkb_keymap_unref(keymap);
  504. /* Shift break caps: unlockOnPress=true (XKB extension) */
  505. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  506. "evdev", "pc105", "us", "",
  507. "shift:breaks_caps-v2");
  508. assert(keymap);
  509. assert(test_key_seq(keymap,
  510. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  511. KEY_A, BOTH, XKB_KEY_A, NEXT,
  512. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  513. KEY_A, BOTH, XKB_KEY_A, NEXT,
  514. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  515. KEY_A, BOTH, XKB_KEY_a, FINISH
  516. ));
  517. xkb_keymap_unref(keymap);
  518. }
  519. static void
  520. test_mod_lock(struct xkb_context *ctx)
  521. {
  522. struct xkb_keymap *keymap;
  523. /*
  524. * Caps unlocks on release (all formats)
  525. * Implicit unlockOnPress=false (XKB spec)
  526. */
  527. for (unsigned int f = 0; f < ARRAY_SIZE(keymap_formats); f++) {
  528. keymap = test_compile_rules(ctx, keymap_formats[f],
  529. "evdev", "pc105", "us", "", "");
  530. assert(keymap);
  531. #define test_caps_unlocks_on_release(keymap) assert( \
  532. test_key_seq((keymap), \
  533. KEY_Y, BOTH, XKB_KEY_y, NEXT, \
  534. /* Lock on press */ \
  535. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT, \
  536. KEY_Y, BOTH, XKB_KEY_Y, NEXT, \
  537. KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, \
  538. /* No unlock on press */ \
  539. KEY_Y, BOTH, XKB_KEY_Y, NEXT, \
  540. KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, \
  541. /* Unlock on release */ \
  542. KEY_Y, BOTH, XKB_KEY_y, FINISH)\
  543. )
  544. test_caps_unlocks_on_release(keymap);
  545. xkb_keymap_unref(keymap);
  546. }
  547. /*
  548. * Caps unlocks on press for format V2
  549. * Explicit unlockOnPress=false (XKB spec)
  550. */
  551. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  552. "evdev", "pc105", "us", "",
  553. "caps:unlock-on-release");
  554. assert(keymap);
  555. test_caps_unlocks_on_release(keymap);
  556. xkb_keymap_unref(keymap);
  557. #undef test_caps_unlocks_on_release
  558. /*
  559. * Caps unlocks on press for format V2
  560. * Explicit unlockOnPress=true (XKB extension)
  561. */
  562. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V2,
  563. "evdev", "pc105", "us", "",
  564. "caps:unlock-on-press");
  565. assert(keymap);
  566. test_key_seq((keymap),
  567. KEY_Y, BOTH, XKB_KEY_y, NEXT,
  568. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  569. /* Lock on press */
  570. KEY_Y, BOTH, XKB_KEY_Y, NEXT,
  571. KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT,
  572. /* Unlock on press */
  573. KEY_Y, BOTH, XKB_KEY_y, NEXT,
  574. KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
  575. KEY_Y, BOTH, XKB_KEY_y, FINISH);
  576. xkb_keymap_unref(keymap);
  577. }
  578. static void
  579. test_mod_latch(struct xkb_context *context)
  580. {
  581. struct xkb_keymap *keymap;
  582. for (unsigned int f = 0; f < ARRAY_SIZE(keymap_formats); f++) {
  583. fprintf(stderr, "=== %s, format %u ===\n", __func__, keymap_formats[f]);
  584. keymap = test_compile_rules(context, keymap_formats[f], "evdev",
  585. "pc104", "latch", "", "");
  586. assert(keymap);
  587. /* Set: basic */
  588. assert(test_key_seq(keymap,
  589. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  590. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  591. /* Empty level */
  592. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT,
  593. KEY_YEN , BOTH, XKB_KEY_NoSymbol, NEXT, /* Prevent latch */
  594. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  595. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  596. /* Unknown key */
  597. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT,
  598. UINT32_MAX , BOTH, XKB_KEY_NoSymbol, NEXT, /* Does not prevent latch */
  599. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  600. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  601. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  602. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L, NEXT,
  603. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Prevent latch */
  604. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L, NEXT,
  605. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  606. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L, NEXT,
  607. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Prevent latch */
  608. KEY_1 , BOTH, XKB_KEY_exclam , NEXT, /* Set is still active */
  609. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L, NEXT,
  610. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  611. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT,
  612. KEY_F1 , BOTH, XKB_KEY_XF86Switch_VT_1, NEXT, /* Prevent latch */
  613. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  614. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  615. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT,
  616. KEY_LVL3 , BOTH, XKB_KEY_ISO_Level3_Shift, NEXT, /* v1: Prevent latch */
  617. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  618. KEY_Q , BOTH, get_keysym(keymap, XKB_KEY_q, XKB_KEY_Q), NEXT,
  619. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT,
  620. KEY_CAPSLOCK , BOTH, XKB_KEY_ISO_Group_Latch , NEXT, /* v1: Prevent latch */
  621. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  622. KEY_Q , BOTH, get_keysym(keymap, XKB_KEY_q, XKB_KEY_Q), FINISH
  623. ));
  624. /* Set: mix with regular set */
  625. assert(test_key_seq(keymap,
  626. KEY_LVL3 , DOWN, XKB_KEY_ISO_Level3_Shift, NEXT, /* Set Level3 (regular) */
  627. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  628. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift (latch) */
  629. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent Shift latch */
  630. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* State unchanged */
  631. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  632. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  633. KEY_LVL3 , UP, XKB_KEY_ISO_Level3_Shift, NEXT, /* Unset Level3 */
  634. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  635. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift (latch) */
  636. KEY_LVL3 , DOWN, XKB_KEY_ISO_Level3_Shift, NEXT, /* Set Level3 (regular) */
  637. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent Shift latch */
  638. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* State unchanged */
  639. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT,
  640. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  641. KEY_LVL3 , UP, XKB_KEY_ISO_Level3_Shift, NEXT, /* Unset Level3 */
  642. KEY_1 , BOTH, XKB_KEY_1 , FINISH
  643. ));
  644. /* Set: mix with regular lock */
  645. assert(test_key_seq(keymap,
  646. /* Only Lock */
  647. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock , NEXT, /* Lock Level3 */
  648. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  649. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift (latch) */
  650. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent Shift latch */
  651. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* State unchanged */
  652. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT, /* Unset shift (latch) */
  653. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  654. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock , NEXT, /* Unlock Level3 */
  655. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  656. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift (latch) */
  657. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock , NEXT, /* Lock Level3 */
  658. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent Shift latch */
  659. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* State unchanged */
  660. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT, /* Unset shift (latch) */
  661. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  662. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock , NEXT, /* Unlock Level3 */
  663. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  664. /* Set, then Lock */
  665. KEY_102ND , DOWN, XKB_KEY_ISO_Level3_Lock , NEXT, /* Set Level3 (lock) */
  666. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  667. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift (latch) */
  668. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent Shift latch */
  669. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* State unchanged */
  670. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT, /* Unset shift (latch) */
  671. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  672. KEY_102ND , UP, XKB_KEY_ISO_Level3_Lock , NEXT, /* Unset and lock Level3 */
  673. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  674. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  675. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock , NEXT, /* Unlock Level3 */
  676. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  677. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift (latch) */
  678. KEY_102ND , DOWN, XKB_KEY_ISO_Level3_Lock , NEXT, /* Set Level3 (lock) */
  679. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent Shift latch */
  680. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* State unchanged */
  681. KEY_LEFTSHIFT , UP, XKB_KEY_Shift_L , NEXT, /* Unset shift (latch) */
  682. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  683. KEY_102ND , UP, XKB_KEY_ISO_Level3_Lock , NEXT, /* Unset and lock Level3 */
  684. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  685. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  686. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock , NEXT, /* Unlock Level3 */
  687. KEY_1 , BOTH, XKB_KEY_1 , FINISH
  688. ));
  689. /* Basic latch/unlatch: breaking/preventing latch */
  690. assert(test_key_seq(keymap,
  691. /* Latch break: sequential */
  692. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, NEXT, /* Latch Shift */
  693. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* No action: unlatch Shift */
  694. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  695. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  696. KEY_F1 , BOTH, XKB_KEY_XF86Switch_VT_1, NEXT, /* VT action: unlatch Shift */
  697. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  698. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  699. KEY_CAPSLOCK , BOTH, XKB_KEY_ISO_Group_Latch, NEXT, /* Group actions do not break latches */
  700. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  701. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  702. /* Latch prevented (DOWN/UP events) */
  703. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L, NEXT, /* Set Shift */
  704. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Prevent latch on DOWN event */
  705. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L, NEXT, /* Unset Shift */
  706. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  707. /* Latch prevented (DOWN event) */
  708. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L, NEXT, /* Set Shift */
  709. KEY_Q , DOWN, XKB_KEY_Q , NEXT, /* Prevent latch */
  710. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L, NEXT, /* Unset Shift */
  711. KEY_Q , UP , XKB_KEY_q , NEXT,
  712. /* Latch not prevented (UP event) */
  713. KEY_Q , DOWN, XKB_KEY_q , NEXT, /* Prevent latch */
  714. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, NEXT, /* Latch Shift */
  715. KEY_Q , UP , XKB_KEY_Q , NEXT, /* Do not prevent latch */
  716. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Unlatch Shift */
  717. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  718. KEY_Q , DOWN, XKB_KEY_q , NEXT,
  719. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L, NEXT, /* Set Shift */
  720. KEY_Q , UP , XKB_KEY_Q , NEXT, /* Do not prevent latch */
  721. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L, NEXT, /* Latch Shift */
  722. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Unlatch Shift */
  723. KEY_Q , BOTH, XKB_KEY_q , FINISH
  724. ));
  725. /* Basic latch/unlatch: not breaking nor preventing latch */
  726. assert(test_key_seq(keymap,
  727. /* No latch break: sequential */
  728. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  729. KEY_RIGHTCTRL , BOTH, XKB_KEY_Control_R , NEXT, /* Modifier action does not break latches */
  730. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Unlatch Shift */
  731. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  732. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  733. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT, /* Modifier action does not break latches */
  734. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift */
  735. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  736. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT,
  737. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  738. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  739. KEY_F2 , BOTH, XKB_KEY_ISO_Group_Shift, NEXT, /* Group action does not break latches */
  740. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Unlatch Shift */
  741. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  742. /* Latch not prevented (DOWN/UP events) */
  743. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  744. KEY_RIGHTCTRL , BOTH, XKB_KEY_Control_R, NEXT,
  745. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* v2: Latch Shift */
  746. KEY_Q , BOTH, get_keysym(keymap, XKB_KEY_q, XKB_KEY_Q), NEXT,
  747. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  748. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT,
  749. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* v2: Latch Shift */
  750. KEY_1 , BOTH, get_keysym(keymap, XKB_KEY_onesuperior, XKB_KEY_exclamdown), NEXT,
  751. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT,
  752. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  753. /* Latch not prevented (DOWN event) */
  754. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  755. KEY_RIGHTCTRL , DOWN, XKB_KEY_Control_R, NEXT,
  756. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* v2: Latch Shift */
  757. KEY_RIGHTCTRL , UP , XKB_KEY_Control_R, NEXT,
  758. KEY_Q , BOTH, get_keysym(keymap, XKB_KEY_q, XKB_KEY_Q), NEXT,
  759. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  760. KEY_102ND , DOWN, XKB_KEY_ISO_Level3_Lock, NEXT,
  761. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* v2: Latch Shift */
  762. KEY_102ND , UP , XKB_KEY_ISO_Level3_Lock, NEXT,
  763. KEY_1 , BOTH, get_keysym(keymap, XKB_KEY_onesuperior, XKB_KEY_exclamdown), NEXT,
  764. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT,
  765. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  766. /* Latch not prevented (UP event) */
  767. KEY_RIGHTCTRL , DOWN, XKB_KEY_Control_R, NEXT,
  768. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  769. KEY_RIGHTCTRL , UP , XKB_KEY_Control_R, NEXT,
  770. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Unlatch Shift */
  771. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  772. KEY_RIGHTCTRL , DOWN, XKB_KEY_Control_R, NEXT,
  773. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  774. KEY_RIGHTCTRL , UP , XKB_KEY_Control_R, NEXT,
  775. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  776. KEY_Q , BOTH, XKB_KEY_Q , NEXT, /* Unlatch Shift */
  777. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  778. KEY_102ND , DOWN, XKB_KEY_ISO_Level3_Lock, NEXT,
  779. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  780. KEY_102ND , UP , XKB_KEY_ISO_Level3_Lock, NEXT,
  781. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift */
  782. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  783. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT,
  784. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  785. KEY_102ND , DOWN, XKB_KEY_ISO_Level3_Lock, NEXT,
  786. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  787. KEY_102ND , UP , XKB_KEY_ISO_Level3_Lock, NEXT,
  788. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  789. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift */
  790. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  791. KEY_102ND , BOTH, XKB_KEY_ISO_Level3_Lock, NEXT,
  792. KEY_1 , BOTH, XKB_KEY_1 , FINISH
  793. ));
  794. /* Latch-to-lock */
  795. assert(test_key_seq(keymap,
  796. /* Lock */
  797. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, NEXT, /* Latch Shift */
  798. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, NEXT, /* Lock Shift */
  799. KEY_Q , BOTH, XKB_KEY_Q , NEXT,
  800. KEY_Q , BOTH, XKB_KEY_Q , NEXT,
  801. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L, NEXT, /* Unlock Shift */
  802. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  803. KEY_Q , BOTH, XKB_KEY_q , NEXT,
  804. /* No lock; cancel latch */
  805. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R, NEXT, /* Latch Shift */
  806. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R, NEXT, /* Unlatch Shift */
  807. KEY_Q , BOTH, XKB_KEY_q , FINISH
  808. // TODO: mix with regular set and lock
  809. ));
  810. /* Sequential (at most one key down at a time) */
  811. assert(test_key_seq(keymap,
  812. /* Latch */
  813. KEY_LEFTCTRL , BOTH, XKB_KEY_Control_L, NEXT, /* Latch Control */
  814. KEY_LEFTALT , BOTH, XKB_KEY_Alt_L , NEXT, /* Latch Alt */
  815. KEY_1 , BOTH, XKB_KEY_plus , NEXT, /* Unlatch Control, Unlatch Alt */
  816. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  817. /* Latch (repeat, no latch-to-lock) */
  818. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , NEXT, /* Latch Shift */
  819. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , NEXT, /* Unlatch Shift (no lock) */
  820. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  821. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT, /* Unlatch all */
  822. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  823. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , NEXT, /* Latch Shift */
  824. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  825. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Shift_R , NEXT, /* Unlatch Shift (no lock) */
  826. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT, /* Unlatch all */
  827. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  828. /* Lock one, latch the other */
  829. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  830. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  831. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  832. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Level3 */
  833. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  834. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  835. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  836. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  837. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  838. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  839. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Level3 */
  840. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  841. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  842. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  843. /* Lock both */
  844. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  845. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  846. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  847. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Lock Level3 */
  848. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  849. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  850. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Unlock Level3 */
  851. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  852. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  853. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  854. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  855. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  856. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  857. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Lock Level3 */
  858. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  859. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  860. KEY_RIGHTALT , BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Unlock Level3 */
  861. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  862. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  863. KEY_1 , BOTH, XKB_KEY_1 , FINISH
  864. ));
  865. // TODO: Sequential with regular set & lock
  866. /* Simultaneous (multiple keys down) */
  867. assert(test_key_seq(keymap,
  868. /* Set */
  869. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  870. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  871. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Prevent latches */
  872. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  873. KEY_1 , BOTH, XKB_KEY_exclam , NEXT, /* Shift still active */
  874. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* Unset Shift */
  875. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  876. /* Set one, latch the other */
  877. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  878. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  879. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift, prevent Level3 latch */
  880. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  881. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  882. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  883. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  884. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift, prevent Level3 latch */
  885. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT, /* Level 3 still active */
  886. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  887. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  888. /* Set both, latch both */
  889. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  890. KEY_LEFTSHIFT , DOWN, XKB_KEY_Shift_L , NEXT, /* Set Shift */
  891. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* v2: Latch Level3 */
  892. KEY_LEFTSHIFT , UP , XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  893. KEY_1 , BOTH, get_keysym(keymap, XKB_KEY_exclam, XKB_KEY_exclamdown), NEXT, /* Unlatch Shift */
  894. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  895. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  896. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  897. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* v2: Latch Level3 */
  898. KEY_1 , BOTH, get_keysym(keymap, XKB_KEY_exclam, XKB_KEY_exclamdown), NEXT, /* Unlatch Shift */
  899. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  900. /* Set one, lock the other */
  901. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  902. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  903. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  904. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  905. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  906. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  907. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT,
  908. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  909. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  910. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  911. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  912. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  913. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  914. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT,
  915. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  916. KEY_1 , BOTH, XKB_KEY_exclam , NEXT,
  917. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  918. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  919. /* Latch one, set the other */
  920. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  921. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  922. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift, prevent Level3 latch */
  923. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  924. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  925. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  926. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  927. KEY_1 , BOTH, XKB_KEY_exclamdown , NEXT, /* Unlatch Shift, prevent Level3 latch */
  928. KEY_1 , BOTH, XKB_KEY_onesuperior , NEXT, /* Level3 still active */
  929. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* Unset Level3 */
  930. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  931. /* Latch one, lock the other */
  932. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  933. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  934. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  935. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* v2: Latch Level3 */
  936. KEY_1 , BOTH, get_keysym(keymap, XKB_KEY_exclam, XKB_KEY_exclamdown), NEXT,
  937. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  938. KEY_1 , BOTH, XKB_KEY_1 , NEXT,
  939. KEY_RIGHTALT , DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, /* Set Level3 */
  940. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Latch Shift */
  941. KEY_RIGHTALT , UP , XKB_KEY_ISO_Level3_Latch, NEXT, /* v2: Latch Level3 */
  942. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Lock Shift */
  943. KEY_1 , BOTH, get_keysym(keymap, XKB_KEY_exclam, XKB_KEY_exclamdown), NEXT,
  944. KEY_LEFTSHIFT , BOTH, XKB_KEY_Shift_L , NEXT, /* Unlock Shift */
  945. KEY_1 , BOTH, XKB_KEY_1 , FINISH
  946. ));
  947. xkb_keymap_unref(keymap);
  948. }
  949. /*
  950. * Mod latch on release (all formats)
  951. * Implicit latchOnPress=false (XKB spec)
  952. */
  953. for (unsigned int f = 0; f < ARRAY_SIZE(keymap_formats); f++) {
  954. keymap = test_compile_rules(context, keymap_formats[f], "evdev",
  955. "pc104", "de", "", "lv3:ralt_latch");
  956. assert(keymap);
  957. #define test_mod_latch_on_release(keymap) assert( \
  958. test_key_seq((keymap), \
  959. KEY_A , BOTH, XKB_KEY_a, NEXT, \
  960. /* Regular latch */ \
  961. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, \
  962. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  963. KEY_A , BOTH, XKB_KEY_a, NEXT, \
  964. /* Latch to lock */ \
  965. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, \
  966. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, \
  967. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  968. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  969. /* Unlock on release */ \
  970. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, \
  971. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  972. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  973. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Latch, NEXT, \
  974. KEY_A , BOTH, XKB_KEY_a, NEXT, \
  975. /* Maintained pressed */ \
  976. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level3_Latch, NEXT, \
  977. /* Degrade to set */ \
  978. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  979. KEY_A , BOTH, XKB_KEY_ae, NEXT, \
  980. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Latch, NEXT, \
  981. KEY_A , BOTH, XKB_KEY_a, FINISH)\
  982. )
  983. test_mod_latch_on_release(keymap);
  984. xkb_keymap_unref(keymap);
  985. }
  986. /*
  987. * Mod latch on release for format V2
  988. * Explicit latchOnPress=false (XKB spec)
  989. */
  990. keymap = test_compile_rules(context, XKB_KEYMAP_FORMAT_TEXT_V2, "evdev",
  991. "pc104", "de", "", "lv3:ralt_latch,lv3:latchOnRelease");
  992. assert(keymap);
  993. test_mod_latch_on_release(keymap);
  994. xkb_keymap_unref(keymap);
  995. #undef test_mod_latch_on_release
  996. /*
  997. * Mod latch on press for format V2
  998. * Explicit latchOnPress=true (XKB extension)
  999. */
  1000. keymap = test_compile_rules(context, XKB_KEYMAP_FORMAT_TEXT_V2, "evdev",
  1001. "pc104", "de", "", "lv3:ralt_latch,lv3:latchOnPress");
  1002. assert(keymap);
  1003. assert(test_key_seq(keymap,
  1004. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1005. /* Regular latch */
  1006. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT,
  1007. KEY_A , BOTH, XKB_KEY_ae, NEXT,
  1008. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1009. /* Latch to lock */
  1010. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT,
  1011. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT,
  1012. KEY_A , BOTH, XKB_KEY_ae, NEXT,
  1013. KEY_A , BOTH, XKB_KEY_ae, NEXT,
  1014. /* Unlock on press */
  1015. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level3_Latch, NEXT,
  1016. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1017. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1018. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Latch, NEXT,
  1019. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1020. /* Maintained pressed: latched on press */
  1021. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level3_Latch, NEXT,
  1022. KEY_A , BOTH, XKB_KEY_ae, NEXT,
  1023. /* Broken latch */
  1024. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1025. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Latch, NEXT,
  1026. KEY_A , BOTH, XKB_KEY_a, FINISH));
  1027. xkb_keymap_unref(keymap);
  1028. /*
  1029. * If `Caps_Lock` is on the second level of some key, and `Shift` is
  1030. * latched, pressing the key locks `Caps` while also breaking the `Shift`
  1031. * latch, ensuring that the next character is properly uppercase.
  1032. *
  1033. * Implemented using: multiple actions per level + VoidAction()
  1034. */
  1035. const char lock_breaks_latch[] =
  1036. "xkb_keymap {\n"
  1037. " xkb_keycodes { <lshift> = 50; <a> = 38; };\n"
  1038. " xkb_types { include \"basic\" };\n"
  1039. " xkb_compat {\n"
  1040. " interpret ISO_Level2_Latch {\n"
  1041. " action = LatchMods(modifiers=Shift,latchToLock,clearLocks);\n"
  1042. " };\n"
  1043. /* Activating CapsLock will break all latches */
  1044. " interpret Caps_Lock {\n"
  1045. " action = {LockMods(modifiers=Lock), VoidAction()};\n"
  1046. " };\n"
  1047. " };\n"
  1048. " xkb_symbols {\n"
  1049. " key <lshift> { [ISO_Level2_Latch, Caps_Lock], type=\"ALPHABETIC\" };\n"
  1050. " key <a> { [a, A] };\n"
  1051. " };\n"
  1052. "};";
  1053. keymap = test_compile_buffer(context, XKB_KEYMAP_FORMAT_TEXT_V2,
  1054. lock_breaks_latch, sizeof(lock_breaks_latch));
  1055. assert(keymap);
  1056. assert(test_key_seq(keymap,
  1057. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1058. /* Regular latch */
  1059. KEY_LEFTSHIFT, BOTH, XKB_KEY_ISO_Level2_Latch, NEXT,
  1060. KEY_A , BOTH, XKB_KEY_A, NEXT,
  1061. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1062. /* Trigger CapsLock */
  1063. KEY_LEFTSHIFT, BOTH, XKB_KEY_ISO_Level2_Latch, NEXT,
  1064. KEY_LEFTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1065. /* CapsLock active, latch broken */
  1066. KEY_A , BOTH, XKB_KEY_A, NEXT,
  1067. KEY_A , BOTH, XKB_KEY_A, NEXT,
  1068. /* Unlock Caps */
  1069. KEY_LEFTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1070. KEY_A , BOTH, XKB_KEY_a, NEXT,
  1071. KEY_A , BOTH, XKB_KEY_a, FINISH));
  1072. xkb_keymap_unref(keymap);
  1073. /*
  1074. * Make a latch break a previous latch on the German E1 layout.
  1075. *
  1076. * Implemented using: multiple actions per level + VoidAction()
  1077. */
  1078. const char lv5_latch_breaks_lv3_latch[] =
  1079. "xkb_keymap {\n"
  1080. " xkb_keycodes { <lshift> = 50; <ralt> = 108; <e> = 26; <f> = 41; };\n"
  1081. " xkb_types { include \"complete\" };\n"
  1082. " xkb_compat { include \"complete\" };\n"
  1083. " xkb_symbols {\n"
  1084. " virtual_modifiers LevelFive;\n"
  1085. " key <lshift> { [ISO_Level2_Latch], [LatchMods(modifiers=Shift)]};\n"
  1086. " key <ralt> { [ISO_Level3_Latch] };\n"
  1087. /* Excerpt from the German E1 `de(e1)` layout */
  1088. " key.type = \"EIGHT_LEVEL_SEMIALPHABETIC\";\n"
  1089. " key <e> { [e, E, EuroSign, any, schwa, SCHWA] };\n"
  1090. " key <f> { [f, F, ISO_Level5_Latch, any, any, any ],\n"
  1091. /* Use VoidAction() to break previous latches */
  1092. " [NoAction(), NoAction(), {VoidAction(), LatchMods(modifiers=LevelFive)}] };\n"
  1093. " };\n"
  1094. "};";
  1095. keymap = test_compile_buffer(context, XKB_KEYMAP_FORMAT_TEXT_V2,
  1096. lv5_latch_breaks_lv3_latch,
  1097. sizeof(lv5_latch_breaks_lv3_latch));
  1098. assert(keymap);
  1099. assert(test_key_seq(keymap,
  1100. KEY_E , BOTH, XKB_KEY_e, NEXT,
  1101. /* Level 3 latch */
  1102. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT,
  1103. KEY_E , BOTH, XKB_KEY_EuroSign, NEXT,
  1104. KEY_E , BOTH, XKB_KEY_e, NEXT,
  1105. /* Level 3 latch */
  1106. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT,
  1107. /* Level 5 latch */
  1108. KEY_F, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT,
  1109. /* Level 3 latch broken, level 5 latch active */
  1110. KEY_E , BOTH, XKB_KEY_schwa, NEXT,
  1111. KEY_E , BOTH, XKB_KEY_e, NEXT,
  1112. /* Level 3 latch */
  1113. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT,
  1114. /* Level 5 latch */
  1115. KEY_F, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT,
  1116. /* Level 3 latch broken, level 5 latch active */
  1117. KEY_LEFTSHIFT, BOTH, XKB_KEY_ISO_Level2_Latch, NEXT,
  1118. /* Shift + level 5 latches */
  1119. KEY_E , BOTH, XKB_KEY_SCHWA, NEXT,
  1120. KEY_E , BOTH, XKB_KEY_e, FINISH));
  1121. xkb_keymap_unref(keymap);
  1122. }
  1123. struct key_properties {
  1124. const char *name;
  1125. bool repeats;
  1126. xkb_mod_mask_t vmodmap;
  1127. };
  1128. static void
  1129. test_explicit_actions(struct xkb_context *ctx)
  1130. {
  1131. struct xkb_keymap *original = test_compile_file(
  1132. ctx, XKB_KEYMAP_FORMAT_TEXT_V1, "keymaps/explicit-actions.xkb"
  1133. );
  1134. assert(original);
  1135. /* Reload keymap from its dump */
  1136. char *dump = xkb_keymap_get_as_string(original,
  1137. XKB_KEYMAP_USE_ORIGINAL_FORMAT);
  1138. assert(dump);
  1139. struct xkb_keymap *roundtrip =
  1140. test_compile_string(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, dump);
  1141. free(dump);
  1142. struct xkb_keymap *keymaps[] = { original, roundtrip };
  1143. for (unsigned int k = 0; k < ARRAY_SIZE(keymaps); k++) {
  1144. assert(keymaps[k]);
  1145. /*
  1146. * <LALT>: Groups 1 & 3 have no explicit actions while group 2 does.
  1147. * We expect that groups 1 & 3 will have the corresponding interpret run
  1148. * to set their actions.
  1149. *
  1150. * <LVL3> has explicit actions on group 2; dumping the keymap forces
  1151. * explicit actions as well as the essential virtualMods=LevelThree field.
  1152. *
  1153. * <AD05> has explicit actions on group 2; dumping the keymap forces
  1154. * explicit actions as well as repeat=Yes.
  1155. */
  1156. const struct key_properties keys[] = {
  1157. { .name = "LALT", .repeats = false, .vmodmap = 0 },
  1158. { .name = "LVL3", .repeats = false, .vmodmap = UINT32_C(1) << 10 },
  1159. { .name = "AD05", .repeats = true , .vmodmap = 0 },
  1160. /* No explicit actions, check defaults */
  1161. { .name = "AD06", .repeats = true , .vmodmap = 0 },
  1162. };
  1163. for (unsigned int i = 0; i < ARRAY_SIZE(keys); i++) {
  1164. xkb_keycode_t kc = xkb_keymap_key_by_name(keymaps[k], keys[i].name);
  1165. assert(kc != XKB_KEYCODE_INVALID);
  1166. assert(keys[i].repeats == xkb_keymap_key_repeats(keymaps[k], kc));
  1167. assert(keys[i].vmodmap == keymaps[k]->keys[kc].vmodmap);
  1168. }
  1169. assert(test_key_seq(
  1170. keymaps[k],
  1171. KEY_Y, BOTH, XKB_KEY_y, NEXT,
  1172. KEY_LEFTALT, DOWN, XKB_KEY_Shift_L, NEXT,
  1173. KEY_Y, BOTH, XKB_KEY_Y, NEXT,
  1174. KEY_LEFTALT, UP, XKB_KEY_Shift_L, NEXT,
  1175. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1176. KEY_Y, BOTH, XKB_KEY_z, NEXT,
  1177. KEY_LEFTALT, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1178. KEY_Y, BOTH, XKB_KEY_leftarrow, NEXT,
  1179. KEY_LEFTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1180. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1181. KEY_Y, BOTH, XKB_KEY_k, NEXT,
  1182. KEY_LEFTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
  1183. KEY_Y, BOTH, XKB_KEY_exclamdown, NEXT,
  1184. KEY_LEFTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT,
  1185. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1186. KEY_LEFTALT, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1187. KEY_Y, BOTH, XKB_KEY_Greek_kappa, NEXT,
  1188. KEY_LEFTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1189. KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1190. KEY_Y, BOTH, XKB_KEY_k, FINISH
  1191. ));
  1192. xkb_keymap_unref(keymaps[k]);
  1193. }
  1194. }
  1195. static void
  1196. test_simultaneous_modifier_clear(struct xkb_context *context)
  1197. {
  1198. struct xkb_keymap *keymap;
  1199. keymap = test_compile_rules(context, XKB_KEYMAP_FORMAT_TEXT_V1, "evdev",
  1200. "pc104", "simultaneous-mods-latches", "", "");
  1201. assert(keymap);
  1202. /*
  1203. * Github issue #583: simultaneous latches of *different* modifiers should
  1204. * not affect each other when clearing their mods.
  1205. */
  1206. /* Original key sequence reported in the issue */
  1207. assert(test_key_seq(keymap,
  1208. KEY_LEFTCTRL, DOWN, XKB_KEY_Control_L , NEXT, /* Set Control */
  1209. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT, /* Latch Level5 */
  1210. KEY_LEFTCTRL, UP , XKB_KEY_Control_L , NEXT, /* Unset Control */
  1211. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  1212. KEY_Z , BOTH, XKB_KEY_ydiaeresis , NEXT, /* Unlatch Level3, unlatch Level5 */
  1213. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1214. KEY_Z , BOTH, XKB_KEY_z , FINISH
  1215. ));
  1216. /* Alternative key sequence with only mod latches */
  1217. assert(test_key_seq(keymap,
  1218. KEY_RIGHTCTRL, BOTH, XKB_KEY_Control_R , NEXT, /* Latch Control */
  1219. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT, /* Latch Level5 */
  1220. KEY_LEFTMETA, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  1221. KEY_Z , BOTH, XKB_KEY_ydiaeresis , NEXT, /* Unlatch Control, Level3 and Level5 */
  1222. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1223. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1224. KEY_X , BOTH, XKB_KEY_x , FINISH
  1225. ));
  1226. /* Alternative simplier key sequence */
  1227. assert(test_key_seq(keymap,
  1228. KEY_LEFTMETA, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  1229. KEY_RIGHTMETA, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT, /* Latch Level5 */
  1230. KEY_Z , BOTH, XKB_KEY_ydiaeresis , NEXT, /* Unlatch Level3, unlatch Level5 */
  1231. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1232. KEY_Z , BOTH, XKB_KEY_z , FINISH
  1233. ));
  1234. /*
  1235. * Test same modifier latch but on a different key
  1236. */
  1237. /* Level 3 */
  1238. assert(test_key_seq(keymap,
  1239. KEY_LEFTMETA, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Latch Level3 */
  1240. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Lock Level3 via latch */
  1241. KEY_Z , BOTH, XKB_KEY_y , NEXT, /* Locked Level3 */
  1242. KEY_Z , BOTH, XKB_KEY_y , NEXT,
  1243. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level3_Latch, NEXT, /* Unlock Level3 via latch */
  1244. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1245. KEY_Z , BOTH, XKB_KEY_z , FINISH
  1246. ));
  1247. /* Level 5, via Control latch */
  1248. assert(test_key_seq(keymap,
  1249. KEY_RIGHTCTRL, BOTH, XKB_KEY_Control_R , NEXT, /* Latch Control */
  1250. KEY_RIGHTALT, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT, /* Lock Level5 via latch */
  1251. KEY_RIGHTMETA, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT, /* Latch Level5 */
  1252. KEY_Z , BOTH, XKB_KEY_ezh , NEXT, /* Locked Level5 */
  1253. KEY_Z , BOTH, XKB_KEY_ezh , NEXT,
  1254. KEY_RIGHTMETA, BOTH, XKB_KEY_ISO_Level5_Latch, NEXT, /* Unlock Level5 via latch */
  1255. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1256. KEY_Z , BOTH, XKB_KEY_z , NEXT,
  1257. KEY_X , BOTH, XKB_KEY_x , FINISH
  1258. ));
  1259. xkb_keymap_unref(keymap);
  1260. }
  1261. static void
  1262. test_keymaps(struct xkb_context *ctx, const char* rules)
  1263. {
  1264. struct xkb_keymap *keymap;
  1265. assert(ctx);
  1266. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, "evdev",
  1267. "evdev", "us,il,ru,de", ",,phonetic,neo",
  1268. "grp:alt_shift_toggle,grp:menu_toggle");
  1269. assert(keymap);
  1270. assert(test_key_seq(keymap,
  1271. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1272. KEY_E, BOTH, XKB_KEY_e, NEXT,
  1273. KEY_L, BOTH, XKB_KEY_l, NEXT,
  1274. KEY_L, BOTH, XKB_KEY_l, NEXT,
  1275. KEY_O, BOTH, XKB_KEY_o, FINISH));
  1276. /* Simple shifted level. */
  1277. assert(test_key_seq(keymap,
  1278. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1279. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1280. KEY_E, BOTH, XKB_KEY_E, NEXT,
  1281. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1282. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1283. KEY_L, BOTH, XKB_KEY_l, NEXT,
  1284. KEY_O, BOTH, XKB_KEY_o, FINISH));
  1285. /* Key repeat shifted and unshifted in the middle. */
  1286. assert(test_key_seq(keymap,
  1287. KEY_H, DOWN, XKB_KEY_h, NEXT,
  1288. KEY_H, REPEAT, XKB_KEY_h, NEXT,
  1289. KEY_H, REPEAT, XKB_KEY_h, NEXT,
  1290. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1291. KEY_H, REPEAT, XKB_KEY_H, NEXT,
  1292. KEY_H, REPEAT, XKB_KEY_H, NEXT,
  1293. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1294. KEY_H, REPEAT, XKB_KEY_h, NEXT,
  1295. KEY_H, REPEAT, XKB_KEY_h, NEXT,
  1296. KEY_H, UP, XKB_KEY_h, NEXT,
  1297. KEY_H, BOTH, XKB_KEY_h, FINISH));
  1298. /* Base modifier cleared on key release... */
  1299. assert(test_key_seq(keymap,
  1300. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1301. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1302. KEY_E, BOTH, XKB_KEY_E, NEXT,
  1303. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1304. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1305. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1306. KEY_O, BOTH, XKB_KEY_O, FINISH));
  1307. /* ... But only by the keycode that set it. */
  1308. assert(test_key_seq(keymap,
  1309. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1310. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1311. KEY_E, BOTH, XKB_KEY_E, NEXT,
  1312. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1313. KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT,
  1314. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1315. KEY_O, BOTH, XKB_KEY_O, FINISH));
  1316. /*
  1317. * A base modifier should only be cleared when no other key affecting
  1318. * the modifier is down.
  1319. */
  1320. assert(test_key_seq(keymap,
  1321. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1322. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1323. KEY_E, BOTH, XKB_KEY_E, NEXT,
  1324. KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT,
  1325. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1326. KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT,
  1327. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1328. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1329. KEY_O, BOTH, XKB_KEY_o, FINISH));
  1330. /*
  1331. * Two key presses from the same key (e.g. if two keyboards use the
  1332. * same xkb_state) should only be released after two releases.
  1333. */
  1334. assert(test_key_seq(keymap,
  1335. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1336. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1337. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1338. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1339. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1340. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1341. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1342. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1343. KEY_H, BOTH, XKB_KEY_h, FINISH));
  1344. /* Same as above with locked modifiers. */
  1345. assert(test_key_seq(keymap,
  1346. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1347. KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT,
  1348. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1349. KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT,
  1350. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1351. KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
  1352. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1353. KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
  1354. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1355. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1356. KEY_H, BOTH, XKB_KEY_h, FINISH));
  1357. /* Group switching / locking. */
  1358. assert(test_key_seq(keymap,
  1359. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1360. KEY_E, BOTH, XKB_KEY_e, NEXT,
  1361. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1362. KEY_K, BOTH, XKB_KEY_hebrew_lamed, NEXT,
  1363. KEY_F, BOTH, XKB_KEY_hebrew_kaph, NEXT,
  1364. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1365. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1366. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1367. KEY_O, BOTH, XKB_KEY_o, FINISH));
  1368. assert(test_key_seq(keymap,
  1369. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1370. KEY_LEFTALT, DOWN, XKB_KEY_ISO_Next_Group, NEXT,
  1371. KEY_LEFTALT, UP, XKB_KEY_ISO_Next_Group, NEXT,
  1372. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, FINISH));
  1373. assert(test_key_seq(keymap,
  1374. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT,
  1375. KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Next_Group, NEXT,
  1376. KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Next_Group, NEXT,
  1377. KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH));
  1378. /* Locked modifiers. */
  1379. assert(test_key_seq(keymap,
  1380. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1381. KEY_H, BOTH, XKB_KEY_H, NEXT,
  1382. KEY_E, BOTH, XKB_KEY_E, NEXT,
  1383. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1384. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1385. KEY_O, BOTH, XKB_KEY_O, FINISH));
  1386. assert(test_key_seq(keymap,
  1387. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1388. KEY_E, BOTH, XKB_KEY_e, NEXT,
  1389. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1390. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1391. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1392. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1393. KEY_O, BOTH, XKB_KEY_o, FINISH));
  1394. assert(test_key_seq(keymap,
  1395. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1396. KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT,
  1397. KEY_E, BOTH, XKB_KEY_E, NEXT,
  1398. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1399. KEY_L, BOTH, XKB_KEY_L, NEXT,
  1400. KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
  1401. KEY_O, BOTH, XKB_KEY_O, FINISH));
  1402. assert(test_key_seq(keymap,
  1403. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1404. KEY_E, BOTH, XKB_KEY_e, NEXT,
  1405. KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT,
  1406. KEY_L, BOTH, XKB_KEY_l, NEXT,
  1407. KEY_L, BOTH, XKB_KEY_l, NEXT,
  1408. KEY_O, BOTH, XKB_KEY_o, FINISH));
  1409. /*
  1410. * A key release affecting a locked modifier should clear it
  1411. * regardless of the key press.
  1412. */
  1413. /* assert(test_key_seq(keymap, */
  1414. /* KEY_H, BOTH, XKB_KEY_h, NEXT, */
  1415. /* KEY_CAPSLOCK, DOWN, XKB_KEY_Caps_Lock, NEXT, */
  1416. /* KEY_E, BOTH, XKB_KEY_E, NEXT, */
  1417. /* KEY_L, BOTH, XKB_KEY_L, NEXT, */
  1418. /* KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, */
  1419. /* KEY_L, BOTH, XKB_KEY_L, NEXT, */
  1420. /* KEY_CAPSLOCK, UP, XKB_KEY_Caps_Lock, NEXT, */
  1421. /* KEY_O, BOTH, XKB_KEY_o, FINISH)); */
  1422. /* Simple Num Lock sanity check. */
  1423. assert(test_key_seq(keymap,
  1424. KEY_KP1, BOTH, XKB_KEY_KP_End, NEXT,
  1425. KEY_NUMLOCK, BOTH, XKB_KEY_Num_Lock, NEXT,
  1426. KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT,
  1427. KEY_KP2, BOTH, XKB_KEY_KP_2, NEXT,
  1428. KEY_NUMLOCK, BOTH, XKB_KEY_Num_Lock, NEXT,
  1429. KEY_KP2, BOTH, XKB_KEY_KP_Down, FINISH));
  1430. /* Test that the aliases in the ru(phonetic) symbols map work. */
  1431. assert(test_key_seq(keymap,
  1432. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1433. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1434. KEY_1, BOTH, XKB_KEY_1, NEXT,
  1435. KEY_Q, BOTH, XKB_KEY_Cyrillic_ya, NEXT,
  1436. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1437. KEY_1, BOTH, XKB_KEY_exclam, NEXT,
  1438. KEY_Q, BOTH, XKB_KEY_Cyrillic_YA, NEXT,
  1439. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1440. KEY_V, BOTH, XKB_KEY_Cyrillic_zhe, NEXT,
  1441. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1442. KEY_1, BOTH, XKB_KEY_1, NEXT,
  1443. KEY_V, BOTH, XKB_KEY_Cyrillic_ZHE, NEXT,
  1444. KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT,
  1445. KEY_V, BOTH, XKB_KEY_Cyrillic_zhe, NEXT,
  1446. KEY_RIGHTSHIFT, UP, XKB_KEY_Shift_R, NEXT,
  1447. KEY_V, BOTH, XKB_KEY_Cyrillic_ZHE, FINISH));
  1448. #define KS(name) xkb_keysym_from_name(name, 0)
  1449. /* Test that levels (1-5) in de(neo) symbols map work. */
  1450. assert(test_key_seq(keymap,
  1451. /* Switch to the group. */
  1452. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1453. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1454. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1455. /* Level 1. */
  1456. KEY_1, BOTH, XKB_KEY_1, NEXT,
  1457. KEY_Q, BOTH, XKB_KEY_x, NEXT,
  1458. KEY_KP7, BOTH, XKB_KEY_KP_7, NEXT,
  1459. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1460. /* Level 2 with Shift. */
  1461. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1462. KEY_1, BOTH, XKB_KEY_degree, NEXT,
  1463. KEY_Q, BOTH, XKB_KEY_X, NEXT,
  1464. KEY_KP7, BOTH, KS("U2714"), NEXT,
  1465. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1466. /*
  1467. * XXX: de(neo) uses shift(both_capslock) which causes
  1468. * the interesting result in the next line. Since it's
  1469. * a key release, it doesn't actually lock the modifier,
  1470. * and applications by-and-large ignore the keysym on
  1471. * release(?). Is this a problem?
  1472. */
  1473. KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1474. /* Level 2 with the Lock modifier. */
  1475. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1476. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1477. KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1478. KEY_6, BOTH, XKB_KEY_6, NEXT,
  1479. KEY_H, BOTH, XKB_KEY_S, NEXT,
  1480. KEY_KP3, BOTH, XKB_KEY_KP_3, NEXT,
  1481. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1482. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1483. KEY_RIGHTSHIFT, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1484. KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1485. /* Level 3. */
  1486. KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1487. KEY_6, BOTH, XKB_KEY_cent, NEXT,
  1488. KEY_Q, BOTH, XKB_KEY_ellipsis, NEXT,
  1489. KEY_KP7, BOTH, KS("U2195"), NEXT,
  1490. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1491. KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1492. /* Level 4. */
  1493. KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1494. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1495. KEY_5, BOTH, XKB_KEY_malesymbol, NEXT,
  1496. KEY_E, BOTH, XKB_KEY_Greek_lambda, NEXT,
  1497. KEY_SPACE, BOTH, XKB_KEY_nobreakspace, NEXT,
  1498. KEY_KP8, BOTH, XKB_KEY_intersection, NEXT,
  1499. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1500. KEY_LEFTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1501. KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1502. /* Level 5. */
  1503. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
  1504. /* XXX: xkeyboard-config is borked when de(neo) is
  1505. * not the first group - not our fault. We test
  1506. * Level5 separately below with only de(neo). */
  1507. /* KEY_5, BOTH, XKB_KEY_periodcentered, NEXT, */
  1508. /* KEY_E, BOTH, XKB_KEY_Up, NEXT, */
  1509. /* KEY_SPACE, BOTH, XKB_KEY_KP_0, NEXT, */
  1510. /* KEY_KP8, BOTH, XKB_KEY_KP_Up, NEXT, */
  1511. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1512. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Shift, NEXT,
  1513. KEY_V, BOTH, XKB_KEY_p, FINISH));
  1514. xkb_keymap_unref(keymap);
  1515. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, rules,
  1516. "", "de", "neo", "");
  1517. assert(keymap);
  1518. assert(test_key_seq(keymap,
  1519. /* Level 5. */
  1520. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
  1521. KEY_5, BOTH, XKB_KEY_periodcentered, NEXT,
  1522. KEY_E, BOTH, XKB_KEY_Up, NEXT,
  1523. KEY_SPACE, BOTH, XKB_KEY_KP_0, NEXT,
  1524. KEY_KP8, BOTH, XKB_KEY_KP_Up, NEXT,
  1525. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1526. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Lock, NEXT,
  1527. /* Level 6. */
  1528. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
  1529. KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT,
  1530. KEY_5, BOTH, XKB_KEY_NoSymbol, NEXT,
  1531. KEY_8, BOTH, XKB_KEY_ISO_Left_Tab, NEXT,
  1532. KEY_E, BOTH, XKB_KEY_Up, NEXT,
  1533. KEY_SPACE, BOTH, XKB_KEY_KP_0, NEXT,
  1534. KEY_KP8, BOTH, XKB_KEY_KP_Up, NEXT,
  1535. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1536. KEY_RIGHTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1537. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Lock, NEXT,
  1538. /* Level 7. */
  1539. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
  1540. KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1541. KEY_5, BOTH, KS("U2221"), NEXT,
  1542. KEY_E, BOTH, XKB_KEY_Greek_LAMBDA, NEXT,
  1543. KEY_SPACE, BOTH, KS("U202F"), NEXT,
  1544. KEY_KP8, BOTH, KS("U22C2"), NEXT,
  1545. KEY_ESC, BOTH, XKB_KEY_Escape, NEXT,
  1546. KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1547. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Lock, NEXT,
  1548. /* Level 8. */
  1549. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level5_Shift, NEXT,
  1550. KEY_CAPSLOCK, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1551. KEY_RIGHTSHIFT, DOWN, XKB_KEY_Shift_R, NEXT,
  1552. KEY_TAB, BOTH, XKB_KEY_ISO_Level5_Lock, NEXT,
  1553. KEY_V, BOTH, XKB_KEY_Greek_pi, NEXT,
  1554. KEY_RIGHTSHIFT, UP, XKB_KEY_Caps_Lock, NEXT,
  1555. KEY_V, BOTH, XKB_KEY_asciitilde, NEXT,
  1556. KEY_CAPSLOCK, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1557. KEY_V, BOTH, XKB_KEY_p, NEXT,
  1558. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level5_Lock, NEXT,
  1559. /* Locks Level 5. */
  1560. KEY_V, BOTH, XKB_KEY_Return, FINISH));
  1561. xkb_keymap_unref(keymap);
  1562. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, rules,
  1563. "", "us,il,ru", "",
  1564. "grp:alt_shift_toggle_bidir,grp:menu_toggle");
  1565. assert(keymap);
  1566. assert(test_key_seq(keymap,
  1567. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1568. KEY_LEFTALT, DOWN, XKB_KEY_ISO_Prev_Group, NEXT,
  1569. KEY_LEFTALT, UP, XKB_KEY_ISO_Prev_Group, NEXT,
  1570. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, FINISH));
  1571. assert(test_key_seq(keymap,
  1572. KEY_LEFTALT, DOWN, XKB_KEY_Alt_L, NEXT,
  1573. KEY_LEFTSHIFT, DOWN, XKB_KEY_ISO_Prev_Group, NEXT,
  1574. KEY_LEFTSHIFT, UP, XKB_KEY_ISO_Prev_Group, NEXT,
  1575. KEY_LEFTALT, UP, XKB_KEY_Alt_L, FINISH));
  1576. /* Check backwards (negative) group switching and wrapping. */
  1577. assert(test_key_seq(keymap,
  1578. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1579. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1580. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1581. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1582. KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
  1583. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1584. KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT,
  1585. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1586. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1587. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1588. KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT,
  1589. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1590. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1591. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1592. KEY_LEFTALT, BOTH, XKB_KEY_ISO_Prev_Group, NEXT,
  1593. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1594. KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
  1595. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1596. KEY_H, BOTH, XKB_KEY_h, FINISH));
  1597. xkb_keymap_unref(keymap);
  1598. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, rules,
  1599. "", "us,il,ru", "",
  1600. "grp:switch,grp:lswitch,grp:menu_toggle");
  1601. assert(keymap);
  1602. /* Test depressed group works (Mode_switch). */
  1603. assert(test_key_seq(keymap,
  1604. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1605. KEY_RIGHTALT, DOWN, XKB_KEY_Mode_switch, NEXT,
  1606. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1607. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1608. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1609. KEY_RIGHTALT, DOWN, XKB_KEY_Mode_switch, NEXT,
  1610. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1611. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1612. KEY_H, BOTH, XKB_KEY_h, FINISH));
  1613. /* Test locked+depressed group works, with wrapping and accumulation. */
  1614. assert(test_key_seq(keymap,
  1615. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1616. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1617. KEY_LEFTALT, DOWN, XKB_KEY_Mode_switch, NEXT,
  1618. KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
  1619. KEY_LEFTALT, UP, XKB_KEY_Mode_switch, NEXT,
  1620. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1621. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1622. KEY_LEFTALT, DOWN, XKB_KEY_Mode_switch, NEXT,
  1623. /* Should wrap back to first group. */
  1624. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1625. KEY_LEFTALT, UP, XKB_KEY_Mode_switch, NEXT,
  1626. KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
  1627. KEY_COMPOSE, BOTH, XKB_KEY_ISO_Next_Group, NEXT,
  1628. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1629. /* Two SetGroup(+1)'s should add up. */
  1630. KEY_RIGHTALT, DOWN, XKB_KEY_Mode_switch, NEXT,
  1631. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1632. KEY_LEFTALT, DOWN, XKB_KEY_Mode_switch, NEXT,
  1633. KEY_H, BOTH, XKB_KEY_Cyrillic_er, NEXT,
  1634. KEY_LEFTALT, UP, XKB_KEY_Mode_switch, NEXT,
  1635. KEY_H, BOTH, XKB_KEY_hebrew_yod, NEXT,
  1636. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, NEXT,
  1637. KEY_H, BOTH, XKB_KEY_h, FINISH));
  1638. xkb_keymap_unref(keymap);
  1639. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, rules,
  1640. "", "us", "euro", "");
  1641. assert(keymap);
  1642. assert(test_key_seq(keymap,
  1643. KEY_5, BOTH, XKB_KEY_5, NEXT,
  1644. KEY_RIGHTALT, DOWN, XKB_KEY_ISO_Level3_Shift, NEXT,
  1645. KEY_5, BOTH, XKB_KEY_EuroSign, NEXT,
  1646. KEY_RIGHTALT, UP, XKB_KEY_ISO_Level3_Shift, FINISH));
  1647. xkb_keymap_unref(keymap);
  1648. keymap = test_compile_file(
  1649. ctx, XKB_KEYMAP_FORMAT_TEXT_V1, "keymaps/unbound-vmod.xkb"
  1650. );
  1651. assert(keymap);
  1652. assert(test_key_seq(keymap,
  1653. KEY_H, BOTH, XKB_KEY_h, NEXT,
  1654. KEY_Z, BOTH, XKB_KEY_y, NEXT,
  1655. KEY_MINUS, BOTH, XKB_KEY_ssharp, NEXT,
  1656. KEY_Z, BOTH, XKB_KEY_y, FINISH));
  1657. xkb_keymap_unref(keymap);
  1658. keymap = test_compile_rules(ctx, XKB_KEYMAP_FORMAT_TEXT_V1, rules,
  1659. "applealu_ansi", "us", "",
  1660. "terminate:ctrl_alt_bksp");
  1661. assert(keymap);
  1662. assert(test_key_seq(keymap,
  1663. KEY_5, BOTH, XKB_KEY_5, NEXT,
  1664. KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT,
  1665. KEY_NUMLOCK, BOTH, XKB_KEY_Clear, NEXT,
  1666. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1667. KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT,
  1668. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1669. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1670. KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT,
  1671. KEY_LEFTSHIFT, DOWN, XKB_KEY_Shift_L, NEXT,
  1672. KEY_KP1, BOTH, XKB_KEY_KP_1, NEXT,
  1673. KEY_LEFTSHIFT, UP, XKB_KEY_Shift_L, NEXT,
  1674. KEY_CAPSLOCK, BOTH, XKB_KEY_Caps_Lock, NEXT,
  1675. KEY_A, BOTH, XKB_KEY_a, FINISH));
  1676. xkb_keymap_unref(keymap);
  1677. }
  1678. int
  1679. main(void)
  1680. {
  1681. test_init();
  1682. struct xkb_context *ctx = test_get_context(CONTEXT_NO_FLAG);
  1683. assert(ctx);
  1684. /* Usual rules */
  1685. test_keymaps(ctx, "evdev");
  1686. /* Special rules to make no use of modmaps */
  1687. test_keymaps(ctx, "evdev-pure-virtual-mods");
  1688. test_simultaneous_modifier_clear(ctx);
  1689. test_group_lock(ctx);
  1690. test_group_latch(ctx);
  1691. test_mod_set(ctx);
  1692. test_mod_lock(ctx);
  1693. test_mod_latch(ctx);
  1694. test_explicit_actions(ctx);
  1695. xkb_context_unref(ctx);
  1696. return EXIT_SUCCESS;
  1697. }