Chain Chain Chain, Chain of Dead Keys

Sorting it all Out
Michael Kaplan's random stuff of dubious value
Be sure to read the disclaimer here first!

Chain Chain Chain, Chain of Dead Keys

  • Comments 11

Over in the Suggestion Box, Van Anderson asked:

I've always wanted to know how to chain dead keys. Since you can't do it in MSKLC, this seems like something that should be out there for the public at large.

Is it as simple as altering the KLC file by adding an '@' after a composite in a dead key list, then giving it its own dead key list? Do you have to do a command line compile with special flags?

Basically, I'm looking for documentation on how to go about doing it for myself, seeing as you were unceremoniously taken off of MSKLC development before you could do everything you wanted.

Now I have mentioned chained dead keys many times in the past:

  1. 17 December 2004 Dead keys are not intuitive
  2. 11 November 2005 What to do with the Vietnamese keyboard on Windows?
  3. 15 November 2005 It is not easy to chain dead keys on Windows
  4. 22 April 2006 Getting all you can out of a keyboard layout, Part #10a
  5. 10 September 2006 Sometimes you *want* to interfere with the keyboard's state buffer
  6. 31 January 2007 A year later, and the Vietnamese keyboard isn't any better
  7. 05 March 2007 It's not just returning 1; it's returning -1
  8. 04 May 2007 The limitations of keyboard layouts (again)
  9. 18 May 2007 Not spacing out on spacing forms of characters
  10. 28 September 2010 Like one of those standards that can't/won't be fully implemented

But I have never truly described how it is done, though I have left broad hints about it -- hints that Van picked up on and clearly was hoping I would perhaps "finish the job". He even supplied some potential motive for me to do so, the reference to how the MSKLC project was transitioned and buried....

Well, I don't require that additional motivation. :-)

But I figure it might be nice to finally put it all out there and explain how it it is done.

And so, without further adieu, I will explain how to chain dead keys on Windows.

First the gratuitous videos for the Chain of Fools song:

    

Okay, with that crucial bit out of the way, I'll continue. :-)

 Now first I'll review some of the consequences of what I am about to tell you:

  • The changes that this blog will talk about making to a .KLC file will make a file that cannot be opened ever again within MSKLC;
  • After you build the keyboard, if you load it in MSKLC the pieces of the layout it does not understand will be silently stripped out;
  • The code within KBDUTOOL.EXE that supports chained dead keys was written over 10 years ago for the KBDTOOL.EXE used by Windows itself, and although the code was never tested (beyond possibly by ad hoc efforts never recorded) of the original developer, it still works despite the fact the two tools have been changed many times and ported to x86, x64, IA64, MIPS, PPC, and Alpha -- living proof that the Software Tester's Axioms I-III have exceptions!
  • I don't ever expect the changes I suggest here to break, but without some kind of testing in place I do wonder if the axioms will catch up at some point. I hope a tester reads this and adds the test case (if you are such a tester send me email and I'll help!),

 Okay, the simple steps, now:

Step 1: Create a simple keyboard like below in MSKLC:

Be sure to put both the upper case and lower case letters on those two keys with letters on them. and do the key that is a dead key just as given above.

Step 2: Build the keyboard from Project | Build DLL and Setup Package.

Step 3: Save out the .KLC file and open it up. If you look at the file, the LAYOUT and DEAD KEY sections should look as follows:

LAYOUT  ;an extra '@' at the end is a dead key

//SC VK_  Cap   0     1    2
//-- ----  ---- ----  ---- ----

16 U       1    u     U    -1   // LATIN SMALL LETTER U, LATIN CAPITAL LETTER U, <none>
18 O       1    o     O    -1   // LATIN SMALL LETTER O, LATIN CAPITAL LETTER O, <none>
28 OEM_7   0    00b4@ -1   -1   // ACUTE ACCENT, <none>, <none>
39 SPACE   0    0020  0020 -1   // SPACE, SPACE, <none>
53 DECIMAL 0    002e  002e -1   // FULL STOP, FULL STOP,

DEADKEY 00b4

00b4 02ba // ´ -> ʺ
0020 00b4 //   -> ´

 As the file says, the @ on the end of 00b4 indicates it is a dead key -- and thus the later dead key table for 00b4 that is being pointed to.

Replace the DEADKEY table there with the following:

DEADKEY 00b4  ; combinations with Acute
00b4    02ba@ ; Acute + Acute -> Double Acute (Modifier Letter Double Prime)
0020    00b4  ; Acute + Space -> Acute

DEADKEY 02ba  ; combinations with Double Acute (Modifier Letter Double Prime)
o       0151  ; Double Acute + o -> Small Letter o With Double Acute
O       0150  ; Double Acute + O -> Capital Letter O With Double Acute
u       0171  ; Double Acute + u -> Small Letter u With Double Acute
U       0170  ; Double Acute + U -> Capital Letter U With Double Acute
0020    2033  ; Double Acute + space -> Double Prime

 Save the file.

Step 4: Build the four DLL files, replacing the files already built.

To do this on my 64-bit machine, I ran the following command line manually from the directory that contained the modified .KLC file and then hand-copied each DLL after it was built to the relevant directory of the setup built in Step 2: (you should substitute the correct path to MSKLC for your install):

C:\Users\michkap\Desktop>"\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\bin\i386\kbdutool.exe" -u -v -w -x layout05.klc

C:\Users\michkap\Desktop>"\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\bin\i386\kbdutool.exe" -u -v -w -m layout05.klc

C:\Users\michkap\Desktop>"\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\bin\i386\kbdutool.exe" -u -v -w -i layout05.klc

C:\Users\michkap\Desktop>"\Program Files (x86)\Microsoft Keyboard Layout Creator 1.4\bin\i386\kbdutool.exe" -u -v -w -o layout05.klc

 Of course if you are automating things you can do the copy after each step.

Just remember that the file can't be opened in MSKLC any more!

Step 5: Install the setup package on a machine.

You will now be able to type

´´u´´U´´o´´O

 to get

űŰőŐ

 and if you ever type anything other than u, o, U, or O for that third character, you will see the ″ (U+2033, aka DOUBLE PRIME) put in for those two acutes.

One last note, you should probably add names for all the dead keys too, they are in a table near the end of the .KLC file:

KEYNAME_DEAD

00b4 "ACUTE ACCENT"

You should add one line for each dead key, even including the ones that can never be produced (since they are still returned by WM_DEADCHAR type messages). Things will still work if you don't do this, but it is a bad practice. For the sake of completeness, I would highly recommend this last step.

Now, there are some interesting things to note here, as you plan out how you might choose characters to use in your own chained dead key containing keyboard:

  • The U+02ba character in this case is never going to appear when you type, because every end point of the various keys replaces it with something else;
  • Every sequence of chained dead keys must end up pointing to a single UTF-16 code point; no sequence can be created;
  • you have to uniquely assign those "midpoint" characters like U+02ba so that each sequence can be uniquely resolved;
  • The very end of each of those special dead key tables should contain a character that won't be too confusing to users, just in case they type a sequence not in your list.

And there you have it: how to chain dead keys in Windows. Hope that helps you out Van. And everyone else! :-)

Comment on the blather
Leave a Comment
  • Please add 5 and 1 and type the answer here:
  • Post
Blog - Comment List
  • Thanks for the tutorial here, Michael. Believe it or not, I will actually use this information. Now I just have to remember how to program batch files...; better find my DOS 5.0 manual - hurrah for dosshell!

    That's one down to creating a comprehensive multi-script keyboard. Now if we can just get rid of the stupid WCHAR restriction. I really want access to the SMP by deadkey or SGCaps. If it makes you feel any better, I fully expected you to answer this pretty soon, but knew I couldn't go wrong appealing to your vanity over losing control of MSKLC - and it worked!

  • The project stuff wasn't really a driver, I found the politics that led to everything getting re-prioritized more annoying than anything else. :-)

    This was on my list to cover at some point, and your question popped up at just the right time....

    I wouldn't hold your breath on the WCHAR limitation getting lifted, though; the code in question is frozen solid, unchanging.

    Of course I believe you're using it; so am I!

  • I'll have to try this.

  • Hey Doug, I kind of thought you might be interested. There are a few others I am hoping to hear from who I expect might be interested too. :-)

  • I expect I may hear from a Marc and a John (or two!) and an Andrew (or two!), as well. :-)

  • It seems I may have inspired myself a little bit. Let me explain. It started when I blogged Chain Chain

  • Yesterday I wrote The Dead Keys Conundrum: An Encyclopedia Brown Mystery about how I figured out a way

  • The Sally Kellerman Addition To The Dead Keys Conundrum: An Encyclopedia Brown Mystery After I wrote

  • So the other day, I was authoring a keyboard....

  • Previous blogs from this series:

    part 5 (...until the decision was made to not refuse to add

  • Coming rather late to this discussion, but someone may still be reading it.

    I wrote a long list of chained deadkeys for classical Greek, where some letters have three different marks on them. When I tried to compile it with kbdutool it stuck at the first line that referred to a second-stage deadkey, and complained that the reference was 'ill-formed'. There seemed no way around this problem.

    So I searched for a commercial program that would handle chained deadkeys, and found one called KbdEdit, inexpensive at about $20. It imports .klc files, and it imported the file I had written without fuss, and made a fully working keyboard.

    So there was nothing wrong with the file I had written. But it looks as if the curse you predicted has struck kbdutool. I was using version 1.4.6002, dated 26 January 2007, in 64-bit Windows 7.

Page 1 of 1 (11 items)