Double-dead keys are an extension of the dead-class keys explained above. Unlike normal dead keys wherein one dead key of type dpf_dead can modify a second of type dpf_mod, double-dead keys employ two consecutive keys of type DPF_DEAD to together modify a third of type DPF_MOD. For example, the key on the German keyboard labeled with single quotes ( `' ) is a double-dead key. When this key is pressed alone and then pressed again shifted, there is no output. But when followed by an appropriate third key, for example the A key, the three keypresses combine to produce an `a' with a circumflex (^) accent (character code $E2). Thus the double-dead pair qualify the output of the A key. The system always keeps the last two down key codes for possible further translation. If they are both of type dpf_dead and the key immediately following is dpf_mod then the two are used to form an index into the (third) key's translation table as follows: In addition to the index found after the dpf_dead qualifier in a normal dead key, a second factor is included in the high nibble of double-dead keys (it is shifted into place with DP_2DFACSHIFT). Its value equals the total number of dead key types + 1 in the keymap. This second index also serves as an identifying flag to the system that two dead keys can be significant. When a key of type dpf_mod is pressed, the system checks the two key codes which preceded the current one. If they were both dpf_dead then the most recent of the two is checked for the double-dead index/flag. If it is found then a new index is formed by multiplying the value in lower nibble with that in the upper. Then, the lower nibble of the least recent DPF_DEAD key is added in to form the final offset. Finally, this last value is used as an index into the translation table of the current, dpf_mod, key. The translation table of all deadable (dpf_mod) keys has [number of dead key types + 1] * [number of double dead key types + 1] entries, arranged in [number of double dead key types + 1] rows of [number of dead key types + 1] entries. This is because as indices are assigned for dead keys in the keymap, those that are double dead keys are assigned the lower numbers. Following is a code fragment from the German (d) keymap source: key0C: DC.B DPF_DEAD,1+(6<<DP_2DFACSHIFT) ; dead ' DC.B DPF_DEAD,2+(6<<DP_2DFACSHIFT) ; dead ` DC.B 0,'=',0,'+' ; =, + key20: ; a, A, ae, AE DC.B DPF_MOD,key20u-key20,DPF_MOD,key20s-key20 DC.B 0,$E6,0,$C6 DC.B 0,$01,0,$01,0,$81,0,$81 ; control translation key20u: DC.B 'a',$E1,$E0,$E2,$E3,$E4 DC.B $E1,$E1,$E2,$E1,$E1,$E1 ; most recent is ' DC.B $E0,$E2,$E0,$E0,$E0,$E0 ; most recent is ` key20s: DC.B 'A',$C1,$C0,$C2,$C3,$C4 DC.B $C1,$C1,$C2,$C1,$C1,$C1 ; most recent is ' DC.B $C0,$C2,$C0,$C0,$C0,$C0 ; most recent is ` Raw key0C, the German single quotes ( `' ) key, is a double dead key. Pressing this key alone, then again while the shift key is down will produce no output but will form a double-dead qualifier. The output of key20 (A), a deadable key, will consequently be modified, producing an "a" with a circumflex (^) accent. The mechanics are as follows: * When key0C is pressed alone the dpf_dead of the first byte pair in the key's table indicates that the key as dead. The second byte is then held by the system. * Next, when key0C is pressed again, this time with the Shift key down, the dpf_dead of the second byte pair (recall that the second pair is used because of the SHIFT qualifier) again indicates the key is a dead key. The second byte of this pair is also held by the system. * Finally, when the A key is pressed the system recalls the latter of the two bytes it has saved. The upper nibble, $6, is multiplied by the lower nibble, $2. The result, $0C, is then added to the lower nibble of the earlier of the two saved bytes, $1. This new value, $0D, is used as an index into the (unshifted) translation table of key20. The character at position $0D is character $E2, an `a' with a circumflex (^) accent. Note About Double Dead Keys. ---------------------------- If only one double-dead key is pressed before a deadable key then the output is the same as if the double-dead were a normal dead key. If shifted key0C is pressed on the German keyboard and then immediately followed by key20, the output produced is character $E0, ` à '. As before, the upper nibble is multiplied with the lower, resulting in $0C. But because there was no second dead-key, this product is used as the final index.