Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.cc

Issue 786813004: Generate correct KeyboardCode (VKEY). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@x430194-xkb
Patch Set: rebase after crrev.com/308447 Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h" 5 #include "ui/events/ozone/layout/xkb/xkb_keyboard_layout_engine.h"
6 6
7 #include <xkbcommon/xkbcommon-names.h> 7 #include <xkbcommon/xkbcommon-names.h>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "ui/events/event_constants.h" 10 #include "ui/events/event_constants.h"
11 #include "ui/events/keycodes/dom3/dom_code.h"
11 #include "ui/events/keycodes/dom3/dom_key.h" 12 #include "ui/events/keycodes/dom3/dom_key.h"
12 #include "ui/events/keycodes/dom4/keycode_converter.h" 13 #include "ui/events/keycodes/dom4/keycode_converter.h"
13 #include "ui/events/ozone/layout/layout_util.h" 14 #include "ui/events/ozone/layout/layout_util.h"
14 #include "ui/events/ozone/layout/xkb/xkb_keyboard_code_conversion.h" 15 #include "ui/events/ozone/layout/xkb/xkb_keyboard_code_conversion.h"
15 16
16 namespace ui { 17 namespace ui {
17 18
18 namespace { 19 namespace {
19 20
20 // Temporarily hard-code an initial layout to test libxkbcommon. 21 // Temporarily hard-code an initial layout to test libxkbcommon.
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
198 case 0x0A: 199 case 0x0A:
199 case 0x0D: 200 case 0x0D:
200 return DomKey::ENTER; 201 return DomKey::ENTER;
201 case 0x1B: 202 case 0x1B:
202 return DomKey::ESCAPE; 203 return DomKey::ESCAPE;
203 default: 204 default:
204 return DomKey::CHARACTER; 205 return DomKey::CHARACTER;
205 } 206 }
206 } 207 }
207 208
208 KeyboardCode DifficultKeyboardCode(DomCode dom_code, 209 KeyboardCode AlphanumericKeyboardCode(base::char16 character) {
209 int flags, 210 // Plain ASCII letters and digits map directly to VKEY values.
210 DomKey dom_key, 211 if ((character >= '0') && (character <= '9'))
211 base::char16 character) { 212 return static_cast<KeyboardCode>(VKEY_0 + character - '0');
212 // TODO(kpschoedel): correct key_code for non-US layouts along the lines 213 if ((character >= 'a') && (character <= 'z'))
213 // of KeyboardCodeFromXKeyEvent() 214 return static_cast<KeyboardCode>(VKEY_A + character - 'a');
214 return DomCodeToKeyboardCode(dom_code); 215 if ((character >= 'A') && (character <= 'Z'))
216 return static_cast<KeyboardCode>(VKEY_A + character - 'A');
217 return VKEY_UNKNOWN;
215 } 218 }
216 219
220 // These tables map layout-dependent printable characters/codes
221 // to legacy Windows-based VKEY values.
222 //
223 // VKEYs are determined by the character produced from a DomCode without
224 // any modifiers, plus zero or more of the DomCode itself, the character
225 // produced with the Shift modifier, and the character produced with the
226 // AltGr modifier.
227
228 // A table of one or more PrintableSubEntry cases applies when the VKEY is
229 // not determined by the unmodified character value alone. Each such table
230 // corresponds to one unmodified character value. For an entry to match,
231 // the dom_code must match, and, if test_X is set, then the character for
232 // the key plus modifier X must also match.
233 struct PrintableSubEntry {
234 DomCode dom_code;
235 bool test_shift : 1;
236 bool test_altgr : 1;
237 base::char16 shift_character;
238 base::char16 altgr_character;
239 KeyboardCode key_code;
240 };
241
242 const base::char16 kNone = 0xFFFE;
243 const base::char16 kAny = 0xFFFF;
244
245 // U+0021 exclamation mark
246 const PrintableSubEntry kU0021[] = {
247 {DomCode::DIGIT1, 0, 0, kAny, kAny, VKEY_1},
248 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
249 {DomCode::SLASH, 0, 0, kAny, kAny, VKEY_OEM_8}};
250
251 // U+0022 quote
252 const PrintableSubEntry kU0022[] = {
253 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_2},
254 {DomCode::DIGIT3, 0, 0, kAny, kAny, VKEY_3}};
255
256 // U+0023 number sign
257 const PrintableSubEntry kU0023[] = {
258 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_7},
259 {DomCode::BACKSLASH, 1, 0, 0x0027, kAny, VKEY_OEM_2}, // apostrophe
260 {DomCode::BACKSLASH, 1, 1, 0x007E, kNone, VKEY_OEM_7}}; // ~, NoSymbol
261
262 // U+0024 dollar sign
263 const PrintableSubEntry kU0024[] = {
264 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_1},
265 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_8}};
266
267 // U+0027 apostrophe
268 const PrintableSubEntry kU0027[] = {
269 {DomCode::DIGIT4, 0, 0, kAny, kAny, VKEY_4},
270 {DomCode::KEY_Q, 0, 0, kAny, kAny, VKEY_OEM_7},
271 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_1},
272 {DomCode::SLASH, 0, 0, kAny, kAny, VKEY_OEM_7},
273 {DomCode::QUOTE, 1, 0, 0x0022, kAny, VKEY_OEM_7}, // quote
274 {DomCode::BACKQUOTE, 1, 0, 0x0022, kAny, VKEY_OEM_3}, // quote
275 {DomCode::BACKQUOTE, 1, 0, 0x00B7, kAny, VKEY_OEM_5}, // middle dot
276 {DomCode::BACKSLASH, 1, 0, kNone, kAny, VKEY_OEM_5}, // NoSymbol
277 {DomCode::MINUS, 1, 1, 0x003F, kNone, VKEY_OEM_4}, // ?, NoSymbol
278 {DomCode::MINUS, 1, 1, 0x003F, 0x00DD, VKEY_OEM_4}, // ?, Y acute
279 {DomCode::EQUAL, 1, 1, 0x002A, kNone, VKEY_OEM_PLUS}, // *, NoSymbol
280 {DomCode::QUOTE, 1, 1, 0x0040, kNone, VKEY_OEM_3}, // @, NoSymbol
281 {DomCode::BACKSLASH, 1, 1, 0x002A, kNone, VKEY_OEM_2}, // *, NoSymbol
282 {DomCode::BACKSLASH, 1, 1, 0x002A, 0x00BD, VKEY_OEM_5}, // *, one half
283 {DomCode::BACKSLASH, 1, 1, 0x002A, 0x0141, VKEY_OEM_2}, // *, L stroke
284 {DomCode::KEY_Z, 1, 1, 0x0022, kNone, VKEY_Z}, // quote, NoSymbol
285 {DomCode::KEY_Z, 1, 1, 0x0022, 0x0158, VKEY_OEM_7}}; // quote, R caron
286
287 // U+0028 left parenthesis
288 const PrintableSubEntry kU0028[] = {
289 {DomCode::DIGIT5, 0, 0, kAny, kAny, VKEY_5},
290 {DomCode::DIGIT9, 0, 0, kAny, kAny, VKEY_9},
291 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
292
293 // U+0029 right parenthesis
294 const PrintableSubEntry kU0029[] = {
295 {DomCode::DIGIT0, 0, 0, kAny, kAny, VKEY_0},
296 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_4},
297 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6}};
298
299 // U+002A *
300 const PrintableSubEntry kU002A[] = {
301 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_1},
302 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
303
304 // U+002B plus sign
305 const PrintableSubEntry kU002B[] = {
306 {DomCode::DIGIT1, 0, 0, kAny, kAny, VKEY_1},
307 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
308 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
309 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
310 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
311 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_2},
312 {DomCode::MINUS, 1, 1, 0x003F, kNone, VKEY_OEM_PLUS}, // ?, NoSymbol
313 {DomCode::MINUS, 1, 1, 0x003F, 0x005C, VKEY_OEM_MINUS}, // ?, backslash
314 {DomCode::MINUS, 1, 1, 0x003F, 0x0151, VKEY_OEM_PLUS}}; // ?, o''
315
316 // U+002C comma
317 const PrintableSubEntry kU002C[] = {
318 {DomCode::DIGIT3, 0, 0, kAny, kAny, VKEY_3},
319 {DomCode::DIGIT5, 0, 0, kAny, kAny, VKEY_5},
320 {DomCode::DIGIT6, 0, 0, kAny, kAny, VKEY_6},
321 {DomCode::DIGIT9, 0, 0, kAny, kAny, VKEY_9},
322 {DomCode::KEY_W, 0, 0, kAny, kAny, VKEY_OEM_COMMA},
323 {DomCode::KEY_V, 0, 0, kAny, kAny, VKEY_OEM_COMMA},
324 {DomCode::KEY_M, 0, 0, kAny, kAny, VKEY_OEM_COMMA},
325 {DomCode::COMMA, 0, 0, kAny, kAny, VKEY_OEM_COMMA}};
326
327 // U+002D hyphen-minus
328 const PrintableSubEntry kU002D[] = {
329 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_2},
330 {DomCode::DIGIT6, 0, 0, kAny, kAny, VKEY_6},
331 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_MINUS},
332 {DomCode::KEY_A, 0, 0, kAny, kAny, VKEY_OEM_MINUS},
333 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_MINUS},
334 {DomCode::SLASH, 1, 0, 0x003D, kAny, VKEY_OEM_MINUS}, // =
335 {DomCode::EQUAL, 1, 1, 0x005F, kNone, VKEY_OEM_MINUS}, // _, NoSymbol
336 {DomCode::EQUAL, 1, 1, 0x005F, 0x0157, VKEY_OEM_4}, // _, r cedilla
337 {DomCode::SLASH, 1, 1, 0x005F, kNone, VKEY_OEM_MINUS}, // _, NoSymbol
338 {DomCode::SLASH, 1, 1, 0x005F, 0x002A, VKEY_OEM_MINUS}, // _, *
339 {DomCode::SLASH, 1, 1, 0x005F, 0x002F, VKEY_OEM_2}, // _, /
340 {DomCode::SLASH, 1, 1, 0x005F, 0x006E, VKEY_OEM_MINUS}}; // _, n
341
342 // U+002E full stop
343 const PrintableSubEntry kU002E[] = {
344 {DomCode::DIGIT7, 0, 0, kAny, kAny, VKEY_7},
345 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
346 {DomCode::KEY_E, 0, 0, kAny, kAny, VKEY_OEM_PERIOD},
347 {DomCode::KEY_R, 0, 0, kAny, kAny, VKEY_OEM_PERIOD},
348 {DomCode::KEY_O, 0, 0, kAny, kAny, VKEY_OEM_PERIOD},
349 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7},
350 {DomCode::PERIOD, 0, 0, kAny, kAny, VKEY_OEM_PERIOD},
351 {DomCode::SLASH, 0, 0, kAny, kAny, VKEY_OEM_2}};
352
353 // U+002F /
354 const PrintableSubEntry kU002F[] = {
355 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_4},
356 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_2},
357 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_7},
358 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5},
359 {DomCode::SLASH, 0, 0, kAny, kAny, VKEY_OEM_2},
360 {DomCode::DIGIT3, 1, 0, 0x0033, kAny, VKEY_3}, // 3
361 {DomCode::DIGIT3, 1, 0, 0x003F, kAny, VKEY_OEM_2}, // ?
362 {DomCode::DIGIT0, 1, 0, 0x0030, kAny, VKEY_0}, // 0
363 {DomCode::DIGIT0, 1, 0, 0x003F, kAny, VKEY_OEM_2}}; // ?
364
365 // U+003A colon
366 const PrintableSubEntry kU003A[] = {
367 {DomCode::DIGIT1, 0, 0, kAny, kAny, VKEY_1},
368 {DomCode::DIGIT5, 0, 0, kAny, kAny, VKEY_5},
369 {DomCode::DIGIT6, 0, 0, kAny, kAny, VKEY_6},
370 {DomCode::PERIOD, 0, 0, kAny, kAny, VKEY_OEM_2}};
371
372 // U+003B semicolon
373 const PrintableSubEntry kU003B[] = {
374 {DomCode::DIGIT4, 0, 0, kAny, kAny, VKEY_4},
375 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
376 {DomCode::KEY_Q, 0, 0, kAny, kAny, VKEY_OEM_1},
377 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_1},
378 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6},
379 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_1},
380 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_3},
381 {DomCode::KEY_Z, 0, 0, kAny, kAny, VKEY_OEM_1},
382 {DomCode::COMMA, 0, 0, kAny, kAny, VKEY_OEM_PERIOD},
383 {DomCode::SLASH, 0, 0, kAny, kAny, VKEY_OEM_2}};
384
385 // U+003D =
386 const PrintableSubEntry kU003D[] = {
387 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
388 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
389 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
390 {DomCode::SLASH, 1, 0, 0x0025, kAny, VKEY_OEM_8}, // %
391 {DomCode::SLASH, 1, 0, 0x002B, kAny, VKEY_OEM_PLUS}, // +
392 {DomCode::MINUS, 1, 1, 0x0025, kNone, VKEY_OEM_PLUS}, // %, NoSymbol
393 {DomCode::MINUS, 1, 1, 0x0025, 0x002D, VKEY_OEM_MINUS}}; // %, -
394
395 // U+003F ?
396 const PrintableSubEntry kU003F[] = {
397 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_2},
398 {DomCode::DIGIT7, 0, 0, kAny, kAny, VKEY_7},
399 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
400 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_PLUS}};
401
402 // U+0040 @
403 const PrintableSubEntry kU0040[] = {
404 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6},
405 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
406
407 // U+005B left square bracket
408 const PrintableSubEntry kU005B[] = {
409 {DomCode::DIGIT1, 0, 0, kAny, kAny, VKEY_OEM_4},
410 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_4},
411 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4},
412 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6},
413 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
414
415 // U+005C backslash
416 const PrintableSubEntry kU005C[] = {
417 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_4},
418 {DomCode::BACKSLASH, 1, 0, 0x002F, kAny, VKEY_OEM_7}, // /
419 {DomCode::BACKSLASH, 1, 0, 0x007C, kAny, VKEY_OEM_5}, // |
420 {DomCode::BACKQUOTE, 1, 1, 0x007C, 0x0031, VKEY_OEM_5}, // |, 1
421 {DomCode::BACKQUOTE, 1, 1, 0x007C, 0x0145, VKEY_OEM_3}}; // |, N cedilla
422
423 // U+005D right square bracket
424 const PrintableSubEntry kU005D[] = {
425 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_OEM_6},
426 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_6},
427 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6},
428 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_3},
429 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
430
431 // U+005F _
432 const PrintableSubEntry kU005F[] = {
433 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
434 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_MINUS}};
435
436 // U+0060 grave accent
437 const PrintableSubEntry kU0060[] = {
438 {DomCode::BACKQUOTE, 1, 0, kNone, kAny, VKEY_OEM_3}, // NoSymbol
439 {DomCode::BACKQUOTE, 1, 0, 0x00AC, kAny, VKEY_OEM_8}, // not
440 {DomCode::BACKQUOTE, 1, 1, 0x007E, kNone, VKEY_OEM_3}, // ~, NoSymbol
441 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0031, VKEY_OEM_3}, // ~, 1
442 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x003B, VKEY_OEM_3}, // ~, ;
443 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0060, VKEY_OEM_3}, // ~, `
444 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x00BF, VKEY_OEM_3}, // ~, inverted ?
445 {DomCode::BACKQUOTE, 1, 1, 0x007E, 0x0151, VKEY_OEM_3}}; // ~, o''
446
447 // U+00A7 section
448 const PrintableSubEntry kU00A7[] = {
449 {DomCode::DIGIT4, 0, 0, kAny, kAny, VKEY_4},
450 {DomCode::DIGIT6, 0, 0, kAny, kAny, VKEY_6},
451 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7},
452 {DomCode::BACKQUOTE, 1, 0, 0x00B0, kAny, VKEY_OEM_2}, // degree
453 {DomCode::BACKQUOTE, 1, 0, 0x00BD, kAny, VKEY_OEM_5}}; // one half
454
455 // U+00AB left-pointing double angle quote
456 const PrintableSubEntry kU00AB[] = {
457 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
458 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_6}};
459
460 // U+00B0 degree
461 const PrintableSubEntry kU00B0[] = {
462 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_2},
463 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
464
465 // U+00BA masculine ordinal indicator
466 const PrintableSubEntry kU00BA[] = {
467 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7},
468 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_OEM_5}};
469
470 // U+00E0 a grave
471 const PrintableSubEntry kU00E0[] = {
472 {DomCode::DIGIT0, 0, 0, kAny, kAny, VKEY_0},
473 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5},
474 {DomCode::QUOTE, 1, 0, 0x00B0, kAny, VKEY_OEM_7}, // degree
475 {DomCode::QUOTE, 1, 0, 0x00E4, kAny, VKEY_OEM_5}}; // a diaeresis
476
477 // U+00E1 a acute
478 const PrintableSubEntry kU00E1[] = {
479 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
480 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
481
482 // U+00E2 a circumflex
483 const PrintableSubEntry kU00E2[] = {
484 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_2},
485 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
486
487 // U+00E4 a diaeresis
488 const PrintableSubEntry kU00E4[] = {
489 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6},
490 {DomCode::QUOTE, 1, 0, 0x00E0, kAny, VKEY_OEM_5}, // a grave
491 {DomCode::QUOTE, 1, 1, 0x00C4, kNone, VKEY_OEM_7}, // A dia., NoSymbol
492 {DomCode::QUOTE, 1, 1, 0x00C4, 0x015A, VKEY_OEM_7}, // A dia., S acute
493 {DomCode::QUOTE, 1, 1, 0x00C4, 0x0159, VKEY_OEM_7}}; // A dia., r caron
494
495 // U+00E6 ae
496 const PrintableSubEntry kU00E6[] = {
497 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_3},
498 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
499
500 // U+00E7 c cedilla
501 const PrintableSubEntry kU00E7[] = {
502 {DomCode::DIGIT9, 0, 0, kAny, kAny, VKEY_9},
503 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4},
504 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6},
505 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7},
506 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_2},
507 {DomCode::COMMA, 0, 0, kAny, kAny, VKEY_OEM_COMMA},
508 {DomCode::SEMICOLON, 1, 1, 0x00C7, kNone, VKEY_OEM_1}, // C ced., NoSy
509 {DomCode::SEMICOLON, 1, 1, 0x00C7, 0x00DE, VKEY_OEM_3}}; // C ced., Thorn
510
511 // U+00E8 e grave
512 const PrintableSubEntry kU00E8[] = {
513 {DomCode::DIGIT7, 0, 0, kAny, kAny, VKEY_7},
514 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_1},
515 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_3}};
516
517 // U+00E9 e acute
518 const PrintableSubEntry kU00E9[] = {
519 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_2},
520 {DomCode::DIGIT0, 0, 0, kAny, kAny, VKEY_0},
521 {DomCode::SLASH, 0, 0, kAny, kAny, VKEY_OEM_2},
522 {DomCode::SEMICOLON, 1, 0, 0x00C9, kAny, VKEY_OEM_1}, // E acute
523 {DomCode::SEMICOLON, 1, 0, 0x00F6, kAny, VKEY_OEM_7}}; // o diaeresis
524
525 // U+00ED i acute
526 const PrintableSubEntry kU00ED[] = {
527 {DomCode::DIGIT9, 0, 0, kAny, kAny, VKEY_9},
528 {DomCode::BACKQUOTE, 0, 0, kAny, kAny, VKEY_0}};
529
530 // U+00F0 eth
531 const PrintableSubEntry kU00F0[] = {
532 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_6},
533 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_1}};
534
535 // U+00F3 o acute
536 const PrintableSubEntry kU00F3[] = {
537 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
538 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
539
540 // U+00F4 o circumflex
541 const PrintableSubEntry kU00F4[] = {
542 {DomCode::DIGIT4, 0, 0, kAny, kAny, VKEY_4},
543 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_1}};
544
545 // U+00F6 o diaeresis
546 const PrintableSubEntry kU00F6[] = {
547 {DomCode::DIGIT0, 0, 0, kAny, kAny, VKEY_OEM_3},
548 {DomCode::MINUS, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
549 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4},
550 {DomCode::SEMICOLON, 1, 0, 0x00E9, kAny, VKEY_OEM_7}, // e acute
551 {DomCode::SEMICOLON, 1, 1, 0x00D6, kNone, VKEY_OEM_3}, // O dia., NoSy
552 {DomCode::SEMICOLON, 1, 1, 0x00D6, 0x0162, VKEY_OEM_3}}; // O dia., T ced.
553
554 // U+00F8 o stroke
555 const PrintableSubEntry kU00F8[] = {
556 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_3},
557 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
558
559 // U+00F9 u grave
560 const PrintableSubEntry kU00F9[] = {
561 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_3},
562 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_2}};
563
564 // U+00FA u acute
565 const PrintableSubEntry kU00FA[] = {
566 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4},
567 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6}};
568
569 // U+00FC u diaeresis
570 const PrintableSubEntry kU00FC[] = {
571 {DomCode::KEY_W, 0, 0, kAny, kAny, VKEY_W},
572 {DomCode::BRACKET_LEFT, 1, 0, 0x00E8, kAny, VKEY_OEM_1}, // e grave
573 {DomCode::MINUS, 1, 1, 0x00DC, kNone, VKEY_OEM_2}, // U dia., NoSy
574 {DomCode::BRACKET_LEFT, 1, 1, 0x00DC, kNone, VKEY_OEM_1}, // U dia., NoSy
575 {DomCode::BRACKET_LEFT, 1, 1, 0x00DC, 0x0141, VKEY_OEM_3}}; // U dia., L-
576
577 // U+0103 a breve
578 const PrintableSubEntry kU0103[] = {
579 {DomCode::DIGIT1, 0, 0, kAny, kAny, VKEY_1},
580 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4}};
581
582 // U+0105 a ogonek
583 const PrintableSubEntry kU0105[] = {
584 {DomCode::DIGIT1, 0, 0, kAny, kAny, VKEY_1},
585 {DomCode::KEY_Q, 0, 0, kAny, kAny, VKEY_Q},
586 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
587
588 // U+010D c caron
589 const PrintableSubEntry kU010D[] = {
590 {DomCode::DIGIT2, 0, 0, kAny, kAny, VKEY_2},
591 {DomCode::DIGIT4, 0, 0, kAny, kAny, VKEY_4},
592 {DomCode::KEY_P, 0, 0, kAny, kAny, VKEY_X},
593 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_1},
594 {DomCode::COMMA, 0, 0, kAny, kAny, VKEY_OEM_COMMA}};
595
596 // U+0111 d stroke
597 const PrintableSubEntry kU0111[] = {
598 {DomCode::DIGIT0, 0, 0, kAny, kAny, VKEY_0},
599 {DomCode::BRACKET_RIGHT, 0, 0, kAny, kAny, VKEY_OEM_6}};
600
601 // U+0117 e dot above
602 const PrintableSubEntry kU0117[] = {
603 {DomCode::DIGIT4, 0, 0, kAny, kAny, VKEY_4},
604 {DomCode::QUOTE, 0, 0, kAny, kAny, VKEY_OEM_7}};
605
606 // U+0119 e ogonek
607 const PrintableSubEntry kU0119[] = {
608 {DomCode::DIGIT3, 0, 0, kAny, kAny, VKEY_3},
609 {DomCode::SLASH, 1, 1, 0x0118, kNone, VKEY_OEM_MINUS}, // E ogonek, NoSy
610 {DomCode::SLASH, 1, 1, 0x0118, 0x006E, VKEY_OEM_2}}; // E ogonek, n
611
612 // U+012F i ogonek
613 const PrintableSubEntry kU012F[] = {
614 {DomCode::DIGIT5, 0, 0, kAny, kAny, VKEY_5},
615 {DomCode::BRACKET_LEFT, 1, 1, 0x012E, kNone, VKEY_OEM_4}}; // Iogonek, NoSy
616
617 // U+0142 l stroke
618 const PrintableSubEntry kU0142[] = {
619 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_1},
620 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_2}};
621
622 // U+015F s cedilla
623 const PrintableSubEntry kU015F[] = {
624 {DomCode::SEMICOLON, 0, 0, kAny, kAny, VKEY_OEM_1},
625 {DomCode::PERIOD, 0, 0, kAny, kAny, VKEY_OEM_PERIOD}};
626
627 // U+0161 s caron
628 const PrintableSubEntry kU0161[] = {
629 {DomCode::DIGIT3, 0, 0, kAny, kAny, VKEY_3},
630 {DomCode::DIGIT6, 0, 0, kAny, kAny, VKEY_6},
631 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4},
632 {DomCode::KEY_A, 0, 0, kAny, kAny, VKEY_OEM_1},
633 {DomCode::KEY_F, 0, 0, kAny, kAny, VKEY_F},
634 {DomCode::PERIOD, 0, 0, kAny, kAny, VKEY_OEM_PERIOD}};
635
636 // U+016B u macron
637 const PrintableSubEntry kU016B[] = {
638 {DomCode::DIGIT8, 0, 0, kAny, kAny, VKEY_8},
639 {DomCode::KEY_Q, 0, 0, kAny, kAny, VKEY_Q},
640 {DomCode::KEY_X, 0, 0, kAny, kAny, VKEY_X}};
641
642 // U+0173 u ogonek
643 const PrintableSubEntry kU0173[] = {
644 {DomCode::DIGIT7, 0, 0, kAny, kAny, VKEY_7},
645 {DomCode::SEMICOLON, 1, 1, 0x0172, kNone, VKEY_OEM_3}, // U ogo., NoSy
646 {DomCode::SEMICOLON, 1, 1, 0x0172, 0x0162, VKEY_OEM_1}}; // U ogo., T ced.
647
648 // U+017C z dot above
649 const PrintableSubEntry kU017C[] = {
650 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_OEM_4},
651 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
652
653 // U+017E z caron
654 const PrintableSubEntry kU017E[] = {
655 {DomCode::DIGIT6, 0, 0, kAny, kAny, VKEY_6},
656 {DomCode::EQUAL, 0, 0, kAny, kAny, VKEY_OEM_PLUS},
657 {DomCode::KEY_W, 0, 0, kAny, kAny, VKEY_W},
658 {DomCode::BRACKET_LEFT, 0, 0, kAny, kAny, VKEY_Y},
659 {DomCode::BACKSLASH, 0, 0, kAny, kAny, VKEY_OEM_5}};
660
661 // Table mapping unshifted characters to PrintableSubEntry tables.
662 struct PrintableMultiEntry {
663 base::char16 plain_character;
664 const PrintableSubEntry* subtable;
665 size_t subtable_size;
666 };
667
668 // Entries are ordered by character value.
669 const PrintableMultiEntry kMultiMap[] = {
670 {0x0021, kU0021, arraysize(kU0021)}, // exclamation mark
671 {0x0022, kU0022, arraysize(kU0022)}, // quotation mark
672 {0x0023, kU0023, arraysize(kU0023)}, // number sign
673 {0x0024, kU0024, arraysize(kU0024)}, // dollar sign
674 {0x0027, kU0027, arraysize(kU0027)}, // apostrophe
675 {0x0028, kU0028, arraysize(kU0028)}, // left parenthesis
676 {0x0029, kU0029, arraysize(kU0029)}, // right parenthesis
677 {0x002A, kU002A, arraysize(kU002A)}, // asterisk
678 {0x002B, kU002B, arraysize(kU002B)}, // plus sign
679 {0x002C, kU002C, arraysize(kU002C)}, // comma
680 {0x002D, kU002D, arraysize(kU002D)}, // hyphen-minus
681 {0x002E, kU002E, arraysize(kU002E)}, // full stop
682 {0x002F, kU002F, arraysize(kU002F)}, // solidus
683 {0x003A, kU003A, arraysize(kU003A)}, // colon
684 {0x003B, kU003B, arraysize(kU003B)}, // semicolon
685 {0x003D, kU003D, arraysize(kU003D)}, // equals sign
686 {0x003F, kU003F, arraysize(kU003F)}, // question mark
687 {0x0040, kU0040, arraysize(kU0040)}, // commercial at
688 {0x005B, kU005B, arraysize(kU005B)}, // left square bracket
689 {0x005C, kU005C, arraysize(kU005C)}, // reverse solidus
690 {0x005D, kU005D, arraysize(kU005D)}, // right square bracket
691 {0x005F, kU005F, arraysize(kU005F)}, // low line
692 {0x0060, kU0060, arraysize(kU0060)}, // grave accent
693 {0x00A7, kU00A7, arraysize(kU00A7)}, // section sign
694 {0x00AB, kU00AB, arraysize(kU00AB)}, // left double angle quotation mark
695 {0x00B0, kU00B0, arraysize(kU00B0)}, // degree sign
696 {0x00BA, kU00BA, arraysize(kU00BA)}, // masculine ordinal indicator
697 {0x00E0, kU00E0, arraysize(kU00E0)}, // a grave
698 {0x00E1, kU00E1, arraysize(kU00E1)}, // a acute
699 {0x00E2, kU00E2, arraysize(kU00E2)}, // a circumflex
700 {0x00E4, kU00E4, arraysize(kU00E4)}, // a diaeresis
701 {0x00E6, kU00E6, arraysize(kU00E6)}, // ae
702 {0x00E7, kU00E7, arraysize(kU00E7)}, // c cedilla
703 {0x00E8, kU00E8, arraysize(kU00E8)}, // e grave
704 {0x00E9, kU00E9, arraysize(kU00E9)}, // e acute
705 {0x00ED, kU00ED, arraysize(kU00ED)}, // i acute
706 {0x00F0, kU00F0, arraysize(kU00F0)}, // eth
707 {0x00F3, kU00F3, arraysize(kU00F3)}, // o acute
708 {0x00F4, kU00F4, arraysize(kU00F4)}, // o circumflex
709 {0x00F6, kU00F6, arraysize(kU00F6)}, // o diaeresis
710 {0x00F8, kU00F8, arraysize(kU00F8)}, // o stroke
711 {0x00F9, kU00F9, arraysize(kU00F9)}, // u grave
712 {0x00FA, kU00FA, arraysize(kU00FA)}, // u acute
713 {0x00FC, kU00FC, arraysize(kU00FC)}, // u diaeresis
714 {0x0103, kU0103, arraysize(kU0103)}, // a breve
715 {0x0105, kU0105, arraysize(kU0105)}, // a ogonek
716 {0x010D, kU010D, arraysize(kU010D)}, // c caron
717 {0x0111, kU0111, arraysize(kU0111)}, // d stroke
718 {0x0117, kU0117, arraysize(kU0117)}, // e dot above
719 {0x0119, kU0119, arraysize(kU0119)}, // e ogonek
720 {0x012F, kU012F, arraysize(kU012F)}, // i ogonek
721 {0x0142, kU0142, arraysize(kU0142)}, // l stroke
722 {0x015F, kU015F, arraysize(kU015F)}, // s cedilla
723 {0x0161, kU0161, arraysize(kU0161)}, // s caron
724 {0x016B, kU016B, arraysize(kU016B)}, // u macron
725 {0x0173, kU0173, arraysize(kU0173)}, // u ogonek
726 {0x017C, kU017C, arraysize(kU017C)}, // z dot above
727 {0x017E, kU017E, arraysize(kU017E)}, // z caron
728 };
729
730 // Table mapping unshifted characters to VKEY values.
731 struct PrintableSimpleEntry {
732 base::char16 plain_character;
733 KeyboardCode key_code;
734 };
735
736 // Entries are ordered by character value.
737 const PrintableSimpleEntry kSimpleMap[] = {
738 {0x0025, VKEY_5}, // percent sign
739 {0x0026, VKEY_1}, // ampersand
740 {0x003C, VKEY_OEM_5}, // less-than sign
741 {0x007B, VKEY_OEM_7}, // left curly bracket
742 {0x007C, VKEY_OEM_5}, // vertical line
743 {0x007D, VKEY_OEM_2}, // right curly bracket
744 {0x007E, VKEY_OEM_5}, // tilde
745 {0x00A1, VKEY_OEM_6}, // inverted exclamation mark
746 {0x00AD, VKEY_OEM_3}, // soft hyphen
747 {0x00B2, VKEY_OEM_7}, // superscript two
748 {0x00B5, VKEY_OEM_5}, // micro sign
749 {0x00BB, VKEY_9}, // right-pointing double angle quotation mark
750 {0x00BD, VKEY_OEM_5}, // vulgar fraction one half
751 {0x00BF, VKEY_OEM_6}, // inverted question mark
752 {0x00DF, VKEY_OEM_4}, // sharp s
753 {0x00E5, VKEY_OEM_6}, // a ring above
754 {0x00EA, VKEY_3}, // e circumflex
755 {0x00EB, VKEY_OEM_1}, // e diaeresis
756 {0x00EC, VKEY_OEM_6}, // i grave
757 {0x00EE, VKEY_OEM_6}, // i circumflex
758 {0x00F1, VKEY_OEM_3}, // n tilde
759 {0x00F2, VKEY_OEM_3}, // o grave
760 {0x00F5, VKEY_OEM_4}, // o tilde
761 {0x00F7, VKEY_OEM_6}, // division sign
762 {0x00FD, VKEY_7}, // y acute
763 {0x00FE, VKEY_OEM_MINUS}, // thorn
764 {0x0101, VKEY_OEM_8}, // a macron
765 {0x0107, VKEY_OEM_7}, // c acute
766 {0x010B, VKEY_OEM_3}, // c dot above
767 {0x0113, VKEY_W}, // e macron
768 {0x011B, VKEY_2}, // e caron
769 {0x011F, VKEY_OEM_6}, // g breve
770 {0x0121, VKEY_OEM_4}, // g dot above
771 {0x0127, VKEY_OEM_6}, // h stroke
772 {0x012B, VKEY_OEM_6}, // i macron
773 {0x0131, VKEY_OEM_1}, // dotless i
774 {0x0137, VKEY_OEM_5}, // k cedilla
775 {0x013C, VKEY_OEM_2}, // l cedilla
776 {0x013E, VKEY_2}, // l caron
777 {0x0146, VKEY_OEM_4}, // n cedilla
778 {0x0148, VKEY_OEM_5}, // n caron
779 {0x0151, VKEY_OEM_4}, // o double acute
780 {0x0159, VKEY_5}, // r caron
781 {0x0163, VKEY_OEM_7}, // t cedilla
782 {0x0165, VKEY_5}, // t caron
783 {0x016F, VKEY_OEM_1}, // u ring above
784 {0x0171, VKEY_OEM_5}, // u double acute
785 {0x01A1, VKEY_OEM_6}, // o horn
786 {0x01B0, VKEY_OEM_4}, // u horn
787 {0x01B6, VKEY_OEM_6}, // z stroke
788 {0x0259, VKEY_OEM_3}, // schwa
789 };
790
217 } // anonymous namespace 791 } // anonymous namespace
218 792
219 XkbKeyCodeConverter::XkbKeyCodeConverter() { 793 XkbKeyCodeConverter::XkbKeyCodeConverter() {
220 } 794 }
221 795
222 XkbKeyCodeConverter::~XkbKeyCodeConverter() { 796 XkbKeyCodeConverter::~XkbKeyCodeConverter() {
223 } 797 }
224 798
225 XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine( 799 XkbKeyboardLayoutEngine::XkbKeyboardLayoutEngine(
226 const XkbKeyCodeConverter& converter) 800 const XkbKeyCodeConverter& converter)
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 bool XkbKeyboardLayoutEngine::UsesAltGr() const { 840 bool XkbKeyboardLayoutEngine::UsesAltGr() const {
267 // NOTIMPLEMENTED(); 841 // NOTIMPLEMENTED();
268 return false; 842 return false;
269 } 843 }
270 844
271 bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code, 845 bool XkbKeyboardLayoutEngine::Lookup(DomCode dom_code,
272 int flags, 846 int flags,
273 DomKey* dom_key, 847 DomKey* dom_key,
274 base::char16* character, 848 base::char16* character,
275 KeyboardCode* key_code) const { 849 KeyboardCode* key_code) const {
850 // Convert DOM physical key to XKB representation.
276 xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code); 851 xkb_keycode_t xkb_keycode = key_code_converter_.DomCodeToXkbKeyCode(dom_code);
277 if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) { 852 if (xkb_keycode == key_code_converter_.InvalidXkbKeyCode()) {
278 LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex 853 LOG(ERROR) << "No XKB keycode for DomCode 0x" << std::hex
279 << static_cast<int>(dom_code) << " '" 854 << static_cast<int>(dom_code) << " '"
280 << KeycodeConverter::DomCodeToCodeString(dom_code) << "'"; 855 << KeycodeConverter::DomCodeToCodeString(dom_code) << "'";
281 return false; 856 return false;
282 } 857 }
283 xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags); 858 xkb_mod_mask_t xkb_flags = EventFlagsToXkbFlags(flags);
859 // Obtain keysym and character.
284 xkb_keysym_t xkb_keysym; 860 xkb_keysym_t xkb_keysym;
285 if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, character)) 861 if (!XkbLookup(xkb_keycode, xkb_flags, &xkb_keysym, character))
286 return false; 862 return false;
287 *dom_key = XkbKeySymToDomKey(xkb_keysym); 863 // Classify the keysym and convert to DOM and VKEY representations.
864 *dom_key = NonPrintableXkbKeySymToDomKey(xkb_keysym);
288 if (*dom_key == DomKey::NONE) { 865 if (*dom_key == DomKey::NONE) {
289 *dom_key = CharacterToDomKey(*character); 866 *dom_key = CharacterToDomKey(*character);
290 *key_code = DifficultKeyboardCode(dom_code, flags, *dom_key, *character); 867 *key_code = AlphanumericKeyboardCode(*character);
868 if (*key_code == VKEY_UNKNOWN) {
869 *key_code = DifficultKeyboardCode(dom_code, flags, xkb_keycode, xkb_flags,
870 xkb_keysym, *dom_key, *character);
871 if (*key_code == VKEY_UNKNOWN)
872 *key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
873 }
291 } else if (*dom_key == DomKey::DEAD) { 874 } else if (*dom_key == DomKey::DEAD) {
292 *character = XkbKeySymDeadKey(xkb_keysym); 875 *character = DeadXkbKeySymToCombiningCharacter(xkb_keysym);
293 *key_code = DomCodeToKeyboardCode(dom_code); 876 *key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
294 } else { 877 } else {
295 *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key); 878 *key_code = NonPrintableDomKeyToKeyboardCode(*dom_key);
296 if (*key_code == VKEY_UNKNOWN) 879 if (*key_code == VKEY_UNKNOWN)
297 *key_code = DomCodeToKeyboardCode(dom_code); 880 *key_code = DomCodeToNonLocatedKeyboardCode(dom_code);
298 } 881 }
299 return true; 882 return true;
300 } 883 }
301 884
302 void XkbKeyboardLayoutEngine::SetKeymap(xkb_keymap* keymap) { 885 void XkbKeyboardLayoutEngine::SetKeymap(xkb_keymap* keymap) {
303 xkb_state_.reset(xkb_state_new(keymap)); 886 xkb_state_.reset(xkb_state_new(keymap));
304 // Update flag map. 887 // Update flag map.
305 static const struct { 888 static const struct {
306 int ui_flag; 889 int ui_flag;
307 const char* xkb_name; 890 const char* xkb_name;
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
348 xkb_state_update_mask(xkb_state_.get(), xkb_flags, 0, 0, 0, 0, 0); 931 xkb_state_update_mask(xkb_state_.get(), xkb_flags, 0, 0, 0, 0, 0);
349 *xkb_keysym = xkb_state_key_get_one_sym(xkb_state_.get(), xkb_keycode); 932 *xkb_keysym = xkb_state_key_get_one_sym(xkb_state_.get(), xkb_keycode);
350 if (*xkb_keysym == XKB_KEY_NoSymbol) 933 if (*xkb_keysym == XKB_KEY_NoSymbol)
351 return false; 934 return false;
352 uint32_t c = xkb_state_key_get_utf32(xkb_state_.get(), xkb_keycode); 935 uint32_t c = xkb_state_key_get_utf32(xkb_state_.get(), xkb_keycode);
353 DLOG_IF(ERROR, c != (c & 0xFFFF)) << "Non-BMP character:" << c; 936 DLOG_IF(ERROR, c != (c & 0xFFFF)) << "Non-BMP character:" << c;
354 *character = static_cast<base::char16>(c); 937 *character = static_cast<base::char16>(c);
355 return true; 938 return true;
356 } 939 }
357 940
941 KeyboardCode XkbKeyboardLayoutEngine::DifficultKeyboardCode(
942 DomCode dom_code,
943 int ui_flags,
944 xkb_keycode_t xkb_keycode,
945 xkb_mod_mask_t xkb_flags,
946 xkb_keysym_t xkb_keysym,
947 DomKey dom_key,
948 base::char16 character) const {
949 // Get the layout interpretation without modifiers, so that
950 // e.g. Ctrl+D correctly generates VKEY_D.
951 xkb_keysym_t plain_keysym;
952 base::char16 plain_character;
953 if (!XkbLookup(xkb_keycode, 0, &plain_keysym, &plain_character))
954 return VKEY_UNKNOWN;
955
956 // If the plain key is non-printable, that determines the VKEY.
957 DomKey plain_key = NonPrintableXkbKeySymToDomKey(plain_keysym);
958 if (plain_key != ui::DomKey::NONE)
959 return NonPrintableDomKeyToKeyboardCode(dom_key);
960
961 // Plain ASCII letters and digits map directly to VKEY values.
962 KeyboardCode key_code = AlphanumericKeyboardCode(plain_character);
963 if (key_code != VKEY_UNKNOWN)
964 return key_code;
965
966 // Check the multi-character tables.
967 const PrintableMultiEntry* multi_end = kMultiMap + arraysize(kMultiMap);
968 const PrintableMultiEntry* multi =
969 std::lower_bound(kMultiMap, multi_end, plain_character,
970 [](const PrintableMultiEntry& e, base::char16 c) {
971 return e.plain_character < c;
972 });
973 if ((multi != multi_end) && (multi->plain_character == plain_character)) {
974 const base::char16 kNonCharacter = kAny;
975 base::char16 shift_character = kNonCharacter;
976 base::char16 altgr_character = kNonCharacter;
977 for (size_t i = 0; i < multi->subtable_size; ++i) {
978 if (multi->subtable[i].dom_code != dom_code)
979 continue;
980 if (multi->subtable[i].test_shift) {
981 if (shift_character == kNonCharacter) {
982 shift_character = XkbSubCharacter(xkb_keycode, xkb_flags, character,
983 ui::EF_SHIFT_DOWN);
984 }
985 if (shift_character != multi->subtable[i].shift_character)
986 continue;
987 }
988 if (multi->subtable[i].test_altgr) {
989 if (altgr_character == kNonCharacter) {
990 altgr_character = XkbSubCharacter(xkb_keycode, xkb_flags, character,
991 ui::EF_ALTGR_DOWN);
992 }
993 if (altgr_character != multi->subtable[i].altgr_character)
994 continue;
995 }
996 return multi->subtable[i].key_code;
997 }
998 }
999
1000 // Check the simple character table.
1001 const PrintableSimpleEntry* simple_end = kSimpleMap + arraysize(kSimpleMap);
1002 const PrintableSimpleEntry* simple =
1003 std::lower_bound(kSimpleMap, simple_end, plain_character,
1004 [](const PrintableSimpleEntry& e, base::char16 c) {
1005 return e.plain_character < c;
1006 });
1007 if ((simple != simple_end) && (simple->plain_character == plain_character))
1008 return simple->key_code;
1009
1010 return VKEY_UNKNOWN;
1011 }
1012
1013 base::char16 XkbKeyboardLayoutEngine::XkbSubCharacter(
1014 xkb_keycode_t xkb_keycode,
1015 xkb_mod_mask_t base_flags,
1016 base::char16 base_character,
1017 int ui_flags) const {
1018 xkb_mod_mask_t flags = EventFlagsToXkbFlags(ui_flags);
1019 if (flags == base_flags)
1020 return base_character;
1021 xkb_keysym_t keysym;
1022 base::char16 character = 0;
1023 if (!XkbLookup(xkb_keycode, flags, &keysym, &character))
1024 character = kNone;
1025 return character;
1026 }
1027
358 } // namespace ui 1028 } // namespace ui
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698