2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
8 #include "keymap_intern.h"
9 #include <devices/inputevent.h>
11 #include <aros/debug.h>
12 #define DEBUG_MAPANSI(x) D(x)
14 /*****************************************************************************
17 #include <clib/keymap_protos.h>
19 AROS_LH5(LONG
, MapANSI
,
22 AROS_LHA(STRPTR
, string
, A0
),
23 AROS_LHA(LONG
, count
, D0
),
24 AROS_LHA(STRPTR
, buffer
, A1
),
25 AROS_LHA(LONG
, length
, D1
),
26 AROS_LHA(struct KeyMap
*, keyMap
, A2
),
29 struct Library
*, KeymapBase
, 8, Keymap
)
32 Convert an ANSI byte string to rawkey codes
35 string - the ANSI byte string to convert
37 count - the number of characters in string
39 buffer - a byte buffer which must be large enough
40 to hold all anticipated code/qualifier pairs
41 which are generated by this function
43 length - maximum anticipation, ie. the buffer size in
44 WORDs (buffer size in bytes divided by two).
45 WORDs, because one code/qualifier pair consists
49 actual - the number of code/qualifier pairs this function
50 generated in buffer. Or an negative value to indicate
61 Contributed by MorphOS team
64 27-11-96 digulla automatically created from
65 keymap_lib.fd and clib/keymap_protos.h
67 *****************************************************************************/
71 LONG OrigLength
=length
;
73 int MaxDoubleDeadIndex
=0;
77 UBYTE DoubleDeadCode
[16];
78 UBYTE DoubleDeadQual
[16];
85 static const UBYTE NumKeys
[] = { 1, 2, 2, 4, 2, 4, 4, 4 };
86 static const UWORD Qualifiers
[8][4] =
89 { 0, IEQUALIFIER_LSHIFT
, },
90 { 0, IEQUALIFIER_LALT
, },
91 { 0, IEQUALIFIER_LSHIFT
, IEQUALIFIER_LALT
, IEQUALIFIER_LSHIFT
| IEQUALIFIER_LALT
},
92 { 0, IEQUALIFIER_CONTROL
, },
93 { 0, IEQUALIFIER_LSHIFT
, IEQUALIFIER_CONTROL
, IEQUALIFIER_LSHIFT
| IEQUALIFIER_CONTROL
},
94 { 0, IEQUALIFIER_LALT
, IEQUALIFIER_CONTROL
, IEQUALIFIER_LALT
| IEQUALIFIER_CONTROL
},
95 { 0, IEQUALIFIER_LSHIFT
, IEQUALIFIER_LALT
, IEQUALIFIER_LSHIFT
| IEQUALIFIER_LALT
},
97 static const UBYTE NumKeys2
[] = { 1, 2, 2, 4, 2, 4, 4, 8 };
98 static const UWORD Qualifiers2
[8][8] =
101 { 0, IEQUALIFIER_LSHIFT
, },
102 { 0, IEQUALIFIER_LALT
, },
103 { 0, IEQUALIFIER_LSHIFT
, IEQUALIFIER_LALT
, IEQUALIFIER_LSHIFT
| IEQUALIFIER_LALT
},
104 { 0, IEQUALIFIER_CONTROL
, },
105 { 0, IEQUALIFIER_LSHIFT
, IEQUALIFIER_CONTROL
, IEQUALIFIER_LSHIFT
| IEQUALIFIER_CONTROL
},
106 { 0, IEQUALIFIER_LALT
, IEQUALIFIER_CONTROL
, IEQUALIFIER_LALT
| IEQUALIFIER_CONTROL
},
107 { 0, IEQUALIFIER_LSHIFT
, IEQUALIFIER_LALT
, IEQUALIFIER_LSHIFT
| IEQUALIFIER_LALT
,
108 IEQUALIFIER_CONTROL
, IEQUALIFIER_CONTROL
| IEQUALIFIER_LSHIFT
,
109 IEQUALIFIER_CONTROL
| IEQUALIFIER_LALT
,
110 IEQUALIFIER_CONTROL
| IEQUALIFIER_LALT
| IEQUALIFIER_LSHIFT
},
113 DEBUG_MAPANSI(bug("MapANSI: string 0x%lx count %ld buffer 0x%lx length %ld KeyMap 0x%lx\n",
114 string
, count
, buffer
, length
, keyMap
));
118 keyMap
= KMBase(KeymapBase
)->DefaultKeymap
;
119 DEBUG_MAPANSI(bug("MapANSI: KeyMap 0x%lx\n", keyMap
));
123 /* First get the list of dead keys.
126 Types
= keyMap
->km_HiKeyMapTypes
+ (0x68 - 0x40);
127 Descrs
= keyMap
->km_HiKeyMap
+ (0x68 - 0x40);
131 for (k
= 0; k
< sizeof(DeadQual
); ++k
)
134 DoubleDeadQual
[k
] = 0xff;
141 unsigned Type
= *--Types
;
142 IPTR Descr
= *--Descrs
;
144 DEBUG_MAPANSI(bug("MapANSI: Code 0x%02x Type 0x%02x Descr 0x%08lx\n",
145 BaseCode
+ Code
, Type
, Descr
));
147 if ((Type
& KCF_NOP
) == 0 && (Type
& KCF_DEAD
) != 0)
149 int Num
= NumKeys2
[Type
& 7];
151 UBYTE
*StrDescr
= (UBYTE
*)Descr
;
153 for (k
= 0; k
< Num
; ++k
)
155 if (StrDescr
[2 * k
] == DPF_DEAD
)
157 int Index
= StrDescr
[2 * k
+ 1] & DP_2DINDEXMASK
;
158 int DoubleDead
= StrDescr
[2 * k
+ 1] >> DP_2DFACSHIFT
;
159 UBYTE MyQual
= Qualifiers2
[Type
& 7][k
];
161 DEBUG_MAPANSI(bug("MapANSI: found dead key index 0x%02lx at 0x%02lx\n",
162 StrDescr
[2 * k
+ 1], BaseCode
+ Code
));
164 if (Index
> MaxDeadIndex
||
165 (DeadQual
[Index
] & MyQual
) == MyQual
)
167 DeadCode
[Index
] = BaseCode
+ Code
;
168 DeadQual
[Index
] = MyQual
;
170 if (Index
> MaxDeadIndex
)
172 MaxDeadIndex
= Index
;
178 if (Index
> MaxDoubleDeadIndex
||
179 (DoubleDeadQual
[Index
] & MyQual
) == MyQual
)
181 DoubleDeadCode
[Index
] = BaseCode
+ Code
;
182 DoubleDeadQual
[Index
] = MyQual
;
184 if (Index
> MaxDoubleDeadIndex
)
186 MaxDoubleDeadIndex
= Index
;
196 Types
= keyMap
->km_LoKeyMapTypes
+ 0x40;
197 Descrs
= keyMap
->km_LoKeyMap
+ 0x40;
201 while (BaseCode
>= 0);
203 NumDeads
= (MaxDoubleDeadIndex
+ 1) * (MaxDeadIndex
+ 1);
205 DEBUG_MAPANSI(bug("MapANSI: MaxDeadIndex %ld MaxDoubleDeadIndex %ld NumDeads %ld\n",
206 MaxDeadIndex
, MaxDoubleDeadIndex
, NumDeads
));
208 /* Now do the real work.
213 unsigned FoundCode
= 0;
214 unsigned FoundQual
= ~0U;
215 unsigned DeadKeyIndex
= 0;
216 UBYTE MyChar
= *string
;
218 DEBUG_MAPANSI(bug("MapANSI: MyChar 0x%02lx count %ld\n",
221 Types
= keyMap
->km_HiKeyMapTypes
+ (0x68 - 0x40);
222 Descrs
= keyMap
->km_HiKeyMap
+ (0x68 - 0x40);
230 unsigned Type
= *--Types
;
231 IPTR Descr
= *--Descrs
;
236 else if (Type
& KCF_DEAD
)
240 int Num
= NumKeys2
[Type
& 7];
242 UBYTE
*StrDescr
= (UBYTE
*)Descr
;
244 for (k
= 0; k
< Num
; ++k
)
246 switch (StrDescr
[2 * k
])
249 if (StrDescr
[2 * k
+ 1] == MyChar
)
251 unsigned MyQual
= Qualifiers2
[Type
& 7][k
];
253 if ((FoundQual
& MyQual
) == MyQual
)
256 FoundCode
= BaseCode
+ Code
;
265 UBYTE
*DeadKeys
= StrDescr
+ StrDescr
[2 * k
+ 1];
268 for (l
= 0; l
< NumDeads
; ++l
)
270 if (DeadKeys
[l
] == MyChar
)
272 unsigned MyQual
= Qualifiers2
[Type
& 7][k
];
275 (l
<= DeadKeyIndex
&&
276 (FoundQual
& MyQual
) == MyQual
))
279 FoundCode
= BaseCode
+ Code
;
291 else if (Type
& KCF_STRING
)
293 int Num
= NumKeys2
[Type
& 7];
295 UBYTE
*StrDescr
= (UBYTE
*)Descr
;
297 for (k
= 0; k
< Num
; ++k
)
299 int Len
= StrDescr
[2 * k
];
300 UBYTE
*KeyStr
= StrDescr
+ StrDescr
[2 * k
+ 1];
302 if (Len
<= count
&& Len
>= FoundLen
)
306 while (i
< Len
&& string
[i
] == KeyStr
[i
])
313 unsigned MyQual
= Qualifiers2
[Type
& 7][k
];
315 if (Len
> FoundLen
|| DeadKeyIndex
||
316 (FoundQual
& MyQual
) == MyQual
)
319 FoundCode
= BaseCode
+ Code
;
327 else if (FoundLen
<= 1)
329 int Num
= NumKeys
[Type
& 7];
333 for (k
= 0; k
< Num
; ++k
)
335 if ((UBYTE
)Descr
== MyChar
)
337 unsigned MyQual
= Qualifiers
[Type
& 7][k
];
339 if (DeadKeyIndex
|| (FoundQual
& MyQual
) == MyQual
)
342 FoundCode
= BaseCode
+ Code
;
351 if (Type
== KC_VANILLA
&& (MyChar
& 0x60) == 0 &&
352 (FoundLen
== 0 || DeadKeyIndex
!= 0))
354 UBYTE MyQual
= IEQUALIFIER_CONTROL
;
358 MyQual
|= IEQUALIFIER_LALT
;
359 Descr2
= (Descr2
>> 16) | (Descr2
<< 16);
362 if ((Descr2
& 0xc0) == 0x40 && (Descr2
& 0x1f) != (MyChar
& 0x1f))
364 MyQual
|= IEQUALIFIER_LSHIFT
;
369 while (k
< 4 && (Descr2
& 0xc0) != 0x40)
375 if (k
< 4 && (Descr2
& 0x1f) == (MyChar
& 0x1f))
378 FoundCode
= BaseCode
+ Code
;
387 Types
= keyMap
->km_LoKeyMapTypes
+ 0x40;
388 Descrs
= keyMap
->km_LoKeyMap
+ 0x40;
392 while (BaseCode
>= 0);
396 DEBUG_MAPANSI(bug("MapANSI: not found\n"));
400 length
-= 1 + (DeadKeyIndex
!= 0) + (DeadKeyIndex
> MaxDeadIndex
);
403 DEBUG_MAPANSI(bug("MapANSI: buffer overflow\n"));
407 DEBUG_MAPANSI(bug("MapANSI: FoundLen %ld Code 0x%02lx Qual 0x%02lx DeadKeyIndex %ld\n",
408 FoundLen
, FoundCode
, FoundQual
, DeadKeyIndex
));
410 if (DeadKeyIndex
!= 0)
412 if (DeadKeyIndex
> MaxDeadIndex
)
414 *buffer
++ = DoubleDeadCode
[DeadKeyIndex
% (MaxDeadIndex
+ 1)];
415 *buffer
++ = DoubleDeadQual
[DeadKeyIndex
% (MaxDeadIndex
+ 1)];
416 DeadKeyIndex
/= (MaxDeadIndex
+ 1);
417 *buffer
++ = DoubleDeadCode
[DeadKeyIndex
];
418 *buffer
++ = DoubleDeadQual
[DeadKeyIndex
];
422 *buffer
++ = DeadCode
[DeadKeyIndex
];
423 *buffer
++ = DeadQual
[DeadKeyIndex
];
426 *buffer
++ = FoundCode
;
427 *buffer
++ = FoundQual
;
433 return OrigLength
- length
;