System/Workbook: gi_RastPort should not be directly accessed
[AROS.git] / rom / keymap / maprawkey.c
blobf1549b170fecc976a7d71557358a60bee438da63
1 /*
2 Copyright © 1995-2007, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: keymap.library function MapRawKey()
6 Lang: english
7 */
8 #include <proto/arossupport.h>
9 #include <devices/inputevent.h>
10 #include <devices/keymap.h>
11 #include "keymap_intern.h"
13 #include <aros/debug.h>
15 /*****************************************************************************
17 NAME */
18 #include <clib/keymap_protos.h>
20 AROS_LH4(WORD, MapRawKey,
22 /* SYNOPSIS */
23 AROS_LHA(struct InputEvent *, event, A0),
24 AROS_LHA(STRPTR , buffer, A1),
25 AROS_LHA(LONG , length, D1),
26 AROS_LHA(struct KeyMap *, keyMap, A2),
28 /* LOCATION */
29 struct Library *, KeymapBase, 7, Keymap)
31 /* FUNCTION
32 Converts IECLASS_RAWKEY events to ANSI bytes.
33 The event list (event->ie_NextEvent) is not traversed!
35 INPUTS
36 event - InputEvent that should be converted.
37 ie_NextEvent is ignored!
39 buffer - buffer into which the mapped ANSI bytes will be put.
41 length - length of buffer.
43 keymap - keymap to use for mapping. If NULL, then the default
44 keymap will be used.
47 RESULT
48 Actual number of chars written to the buffer. A return value of
49 -1 means buffer owerflow.
51 NOTES
53 EXAMPLE
55 BUGS
57 SEE ALSO
58 MapAnsi()
60 INTERNALS
62 HISTORY
63 27-11-96 digulla automatically created from
64 keymap_lib.fd and clib/keymap_protos.h
66 *****************************************************************************/
68 AROS_LIBFUNC_INIT
70 struct BufInfo bufinfo;
71 struct KeyInfo ki;
72 UWORD code, qual;
74 bufinfo.Buffer = buffer;
75 bufinfo.BufLength = length;
76 bufinfo.CharsWritten = 0L;
78 if (!keyMap)
79 keyMap = KMBase(KeymapBase)->DefaultKeymap;
82 /* Don't handle non-rawkey events */
83 if (event->ie_Class != IECLASS_RAWKEY)
84 goto done;
86 code = event->ie_Code;
87 qual = event->ie_Qualifier;
89 /* Get info on keypress */
90 if (!GetKeyInfo(&ki, code, qual, keyMap))
91 goto done; /* Invalid key mapping (like CTRL-ALT-A if a doesn't support CTRL-ALT */
93 /* Handle decoding of the the different keytypes (normal, KCF_STRING, KCF_DEAD and KCF_NOP) */
95 switch (ki.Key_MapType & (KC_NOQUAL|KCF_STRING|KCF_DEAD|KCF_NOP))
97 case KC_NOQUAL:
99 BYTE idx;
100 UBYTE c;
102 D(bug("mrk: KC_NOQUAL\n"));
104 D(bug("mrk: getting idx at [%d][%d]\n", ki.Key_MapType & KC_VANILLA, ki.KCFQual));
105 idx = keymaptype_table[ki.Key_MapType & KC_VANILLA][ki.KCFQual];
107 if (idx != -1)
109 D(bug("mrk: valid qual, idx=%d, key mapping=%04x\n", idx, ki.Key_Mapping));
110 if (idx == -2)
112 D(bug("mrk: Ctrl-C mode\n"));
113 /* Special-case where bit 5 & 6 should be cleared */
114 idx = 3;
115 c = GetMapChar(ki.Key_Mapping, idx);
117 /* clear bit 5 and 6 */
118 c &= ~((1 << 5)|(1 << 6));
120 else
122 c = GetMapChar(ki.Key_Mapping, idx);
125 D(bug("mrk: Putting %c (%d 0x%x) into buffer\n", c, c, c));
127 if (c != 0) /* If we get a 0 from the keymap, it means the char converts to "" */
129 if (!WriteToBuffer(&bufinfo, &c, 1))
130 goto overflow;
133 } /* if (idx != -1) */
134 break;
137 case KCF_STRING:
139 BYTE idx;
141 D(bug("mrk: KCF_STRING\n"));
143 D(bug("mrk: getting idx at [%d][%d]\n", ki.Key_MapType & KC_VANILLA, ki.KCFQual));
144 idx = keymapstr_table[ki.Key_MapType & KC_VANILLA][ki.KCFQual];
146 if (idx != -1)
148 UBYTE *str_descrs = (UBYTE *)ki.Key_Mapping;
149 UBYTE len, offset;
151 /* Since each string descriptor uses two bytes we multiply by 2 */
152 idx *= 2;
154 /* Get string info from string descriptor table */
156 len = str_descrs[idx];
157 offset = str_descrs[idx + 1];
159 D(bug("mrk: len=%d, offset=%d\n", len, offset));
161 /* Write string to buffer */
162 if (!WriteToBuffer(&bufinfo, &(str_descrs[offset]), len))
163 goto overflow;
165 } /* if (idx != -1) */
167 break;
170 case KCF_DEAD:
172 BYTE idx;
174 /* Get the index to the right dead key descrptor */
175 D(bug("mrk: KCF_DEAD\n"));
177 D(bug("mrk: getting idx at [%d][%d]\n", ki.Key_MapType & KC_VANILLA, ki.KCFQual));
178 idx = keymapstr_table[ki.Key_MapType & KC_VANILLA][ki.KCFQual];
180 if (idx != -1)
183 UBYTE *dead_descr = (UBYTE *)ki.Key_Mapping;
184 UBYTE dead_type;
185 UBYTE dead_val;
187 /* Each dead descripto is 2 bytes */
188 idx *= 2;
190 dead_type = dead_descr[idx];
191 dead_val = dead_descr[idx + 1];
194 if (dead_type == 0)
196 /* Val is the key to output */
197 if (!WriteToBuffer(&bufinfo, &dead_val, 1))
198 goto overflow;
200 else if (dead_type == DPF_DEAD)
202 /* Do absolutely nothing. DPF_DEAD keys
203 ** are not possible to output, and are not
204 ** interesting by themselves.
205 ** However, if a DPF_MOD key follows..
209 else if (dead_type == DPF_MOD)
211 /* Now, lets have a look at the last two previous
212 ** keypresses.
214 ** dk_idx defaults to 0, which is the index to use if it turns out that
215 ** the deadable key had no valid deadkeys before it
217 WORD dk_idx = 0; /* Defaults to 0, which is the index to be used into the transition table */
218 WORD dki_1;
220 /* Get deadkey index for Prev1 */
221 dki_1 = GetDeadKeyIndex(event->ie_Prev1DownCode, event->ie_Prev1DownQual, keyMap);
222 if (dki_1 != -1) /* Was it a dead key ? */
224 dk_idx = dki_1;
226 /* Is this a double deadkey (higher nibble set ?) */
227 if (dki_1 >> DP_2DFACSHIFT)
229 WORD dki_2;
231 dk_idx = (dki_1 & DP_2DINDEXMASK) * (dki_1 >> DP_2DFACSHIFT);
233 dki_2 = GetDeadKeyIndex(event->ie_Prev2DownCode, event->ie_Prev2DownQual, keyMap);
234 if (dki_2 != -1) /* Was it a dead key ? */
236 /* Compute deadkey index - explained in RKM:L p. 826 */
237 dk_idx += (dki_2 & DP_2DINDEXMASK);
242 dead_val = dead_descr[dead_val + dk_idx];
244 if (!WriteToBuffer(&bufinfo, &dead_val, 1))
245 goto overflow;
248 else
250 D(bug("Keymap contains illegal deadkey type for code %04x, event->ie_Code\n"));
254 } /* if (idx != -1) */
256 break;
259 case KCF_NOP:
260 break;
262 default:
263 D(bug("Error in keymap, more than one decode action specified for code %04x\n", event->ie_Code));
264 break;
266 } /* switch (ki.Key_MapType & (KC_NOQUAL|KCF_STRING|KCF_DEAD|KCF_NOP)) */
268 done:
269 ReturnInt ("MapRawKey", WORD, bufinfo.CharsWritten);
271 overflow:
272 ReturnInt ("MapRawKey", WORD, -1);
274 AROS_LIBFUNC_EXIT
275 } /* MapRawKey */