| File: | xkmread.c |
| Location: | line 1234, column 9 |
| Description: | Function call argument is an uninitialized value |
| 1 | /************************************************************ | |||||
| 2 | Copyright (c) 1994 by Silicon Graphics Computer Systems, Inc. | |||||
| 3 | ||||||
| 4 | Permission to use, copy, modify, and distribute this | |||||
| 5 | software and its documentation for any purpose and without | |||||
| 6 | fee is hereby granted, provided that the above copyright | |||||
| 7 | notice appear in all copies and that both that copyright | |||||
| 8 | notice and this permission notice appear in supporting | |||||
| 9 | documentation, and that the name of Silicon Graphics not be | |||||
| 10 | used in advertising or publicity pertaining to distribution | |||||
| 11 | of the software without specific prior written permission. | |||||
| 12 | Silicon Graphics makes no representation about the suitability | |||||
| 13 | of this software for any purpose. It is provided "as is" | |||||
| 14 | without any express or implied warranty. | |||||
| 15 | ||||||
| 16 | SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS | |||||
| 17 | SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY | |||||
| 18 | AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON | |||||
| 19 | GRAPHICS BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL | |||||
| 20 | DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, | |||||
| 21 | DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE | |||||
| 22 | OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH | |||||
| 23 | THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||||
| 24 | ||||||
| 25 | ********************************************************/ | |||||
| 26 | ||||||
| 27 | #ifdef HAVE_DIX_CONFIG_H | |||||
| 28 | #include <dix-config.h> | |||||
| 29 | #elif defined(HAVE_CONFIG_H1) | |||||
| 30 | #include <config.h> | |||||
| 31 | #endif | |||||
| 32 | ||||||
| 33 | #include <stdio.h> | |||||
| 34 | ||||||
| 35 | #include <X11/Xos.h> | |||||
| 36 | #include <X11/Xfuncs.h> | |||||
| 37 | ||||||
| 38 | ||||||
| 39 | #include <stdlib.h> | |||||
| 40 | #include <X11/Xlib.h> | |||||
| 41 | #include <X11/keysym.h> | |||||
| 42 | ||||||
| 43 | #include <X11/XKBlib.h> | |||||
| 44 | ||||||
| 45 | #include <X11/extensions/XKBgeom.h> | |||||
| 46 | #include "XKMformat.h" | |||||
| 47 | #include "XKBfileInt.h" | |||||
| 48 | ||||||
| 49 | ||||||
| 50 | #ifndef SEEK_SET0 | |||||
| 51 | #define SEEK_SET0 0 | |||||
| 52 | #endif | |||||
| 53 | ||||||
| 54 | /***====================================================================***/ | |||||
| 55 | ||||||
| 56 | static XPointer | |||||
| 57 | XkmInsureSize(XPointer oldPtr, int oldCount, int *newCountRtrn, int elemSize) | |||||
| 58 | { | |||||
| 59 | int newCount = *newCountRtrn; | |||||
| 60 | ||||||
| 61 | if (oldPtr == NULL((void*)0)) { | |||||
| 62 | if (newCount == 0) | |||||
| 63 | return NULL((void*)0); | |||||
| 64 | oldPtr = (XPointer) _XkbCalloc(newCount, elemSize)calloc((newCount),(elemSize)); | |||||
| 65 | } | |||||
| 66 | else if (oldCount < newCount) { | |||||
| 67 | oldPtr = (XPointer) _XkbRealloc(oldPtr, newCount * elemSize)realloc((oldPtr),(newCount * elemSize)); | |||||
| 68 | if (oldPtr != NULL((void*)0)) { | |||||
| 69 | char *tmp = (char *) oldPtr; | |||||
| 70 | ||||||
| 71 | bzero(&tmp[oldCount * elemSize], (newCount - oldCount) * elemSize)__builtin___memset_chk (&tmp[oldCount * elemSize], 0, (newCount - oldCount) * elemSize, __builtin_object_size (&tmp[oldCount * elemSize], 0)); | |||||
| 72 | } | |||||
| 73 | } | |||||
| 74 | else if (newCount < oldCount) { | |||||
| 75 | *newCountRtrn = oldCount; | |||||
| 76 | } | |||||
| 77 | return oldPtr; | |||||
| 78 | } | |||||
| 79 | ||||||
| 80 | #define XkmInsureTypedSize(p,o,n,t)((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t)))) ((p)=((t *)XkmInsureSize((char *)(p),(o),(n),sizeof(t)))) | |||||
| 81 | ||||||
| 82 | static CARD8 | |||||
| 83 | XkmGetCARD8(FILE * file, int *pNRead) | |||||
| 84 | { | |||||
| 85 | int tmp; | |||||
| 86 | ||||||
| 87 | tmp = getc(file); | |||||
| 88 | if (pNRead && (tmp != EOF(-1))) | |||||
| 89 | (*pNRead) += 1; | |||||
| 90 | return tmp; | |||||
| 91 | } | |||||
| 92 | ||||||
| 93 | static CARD16 | |||||
| 94 | XkmGetCARD16(FILE * file, int *pNRead) | |||||
| 95 | { | |||||
| 96 | CARD16 val; | |||||
| 97 | ||||||
| 98 | if ((fread(&val, 2, 1, file) == 1) && (pNRead)) | |||||
| 99 | (*pNRead) += 2; | |||||
| 100 | return val; | |||||
| 101 | } | |||||
| 102 | ||||||
| 103 | static CARD32 | |||||
| 104 | XkmGetCARD32(FILE * file, int *pNRead) | |||||
| 105 | { | |||||
| 106 | CARD32 val; | |||||
| 107 | ||||||
| 108 | if ((fread(&val, 4, 1, file) == 1) && (pNRead)) | |||||
| 109 | (*pNRead) += 4; | |||||
| 110 | return val; | |||||
| 111 | } | |||||
| 112 | ||||||
| 113 | static int | |||||
| 114 | XkmSkipPadding(FILE * file, unsigned pad) | |||||
| 115 | { | |||||
| 116 | register int i, nRead = 0; | |||||
| 117 | ||||||
| 118 | for (i = 0; i < pad; i++) { | |||||
| 119 | if (getc(file) != EOF(-1)) | |||||
| 120 | nRead++; | |||||
| 121 | } | |||||
| 122 | return nRead; | |||||
| 123 | } | |||||
| 124 | ||||||
| 125 | static int | |||||
| 126 | XkmGetCountedString(FILE * file, char *str, int max_len) | |||||
| 127 | { | |||||
| 128 | int count, nRead = 0; | |||||
| 129 | ||||||
| 130 | count = XkmGetCARD16(file, &nRead); | |||||
| 131 | if (count > 0) { | |||||
| 132 | int tmp; | |||||
| 133 | ||||||
| 134 | if (count > max_len) { | |||||
| 135 | tmp = fread(str, 1, max_len, file); | |||||
| 136 | while (tmp < count) { | |||||
| 137 | if ((getc(file)) != EOF(-1)) | |||||
| 138 | tmp++; | |||||
| 139 | else | |||||
| 140 | break; | |||||
| 141 | } | |||||
| 142 | } | |||||
| 143 | else { | |||||
| 144 | tmp = fread(str, 1, count, file); | |||||
| 145 | } | |||||
| 146 | nRead += tmp; | |||||
| 147 | } | |||||
| 148 | if (count >= max_len) | |||||
| 149 | str[max_len - 1] = '\0'; | |||||
| 150 | else | |||||
| 151 | str[count] = '\0'; | |||||
| 152 | count = XkbPaddedSize(nRead)((((unsigned int)(nRead)+3) >> 2) << 2) - nRead; | |||||
| 153 | if (count > 0) | |||||
| 154 | nRead += XkmSkipPadding(file, count); | |||||
| 155 | return nRead; | |||||
| 156 | } | |||||
| 157 | ||||||
| 158 | /***====================================================================***/ | |||||
| 159 | ||||||
| 160 | static int | |||||
| 161 | ReadXkmVirtualMods(FILE *file, XkbFileInfo *result, XkbChangesPtr changes) | |||||
| 162 | { | |||||
| 163 | register unsigned int i, bit; | |||||
| 164 | unsigned int bound, named, tmp; | |||||
| 165 | int nRead = 0; | |||||
| 166 | XkbDescPtr xkb; | |||||
| 167 | ||||||
| 168 | xkb = result->xkb; | |||||
| 169 | if (XkbAllocServerMap(xkb, XkbVirtualModsMask(1<<6), 0) != Success0) { | |||||
| 170 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmVirtualMods", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmVirtualMods"); _XkbErrData= (0); }; | |||||
| 171 | return -1; | |||||
| 172 | } | |||||
| 173 | bound = XkmGetCARD16(file, &nRead); | |||||
| 174 | named = XkmGetCARD16(file, &nRead); | |||||
| 175 | for (i = tmp = 0, bit = 1; i < XkbNumVirtualMods16; i++, bit <<= 1) { | |||||
| 176 | if (bound & bit) { | |||||
| 177 | xkb->server->vmods[i] = XkmGetCARD8(file, &nRead); | |||||
| 178 | if (changes) | |||||
| 179 | changes->map.vmods |= bit; | |||||
| 180 | tmp++; | |||||
| 181 | } | |||||
| 182 | } | |||||
| 183 | if ((i = XkbPaddedSize(tmp)((((unsigned int)(tmp)+3) >> 2) << 2) - tmp) > 0) | |||||
| 184 | nRead += XkmSkipPadding(file, i); | |||||
| 185 | if (XkbAllocNames(xkb, XkbVirtualModNamesMask(1<<11), 0, 0) != Success0) { | |||||
| 186 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmVirtualMods", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmVirtualMods"); _XkbErrData= (0); }; | |||||
| 187 | return -1; | |||||
| 188 | } | |||||
| 189 | for (i = 0, bit = 1; i < XkbNumVirtualMods16; i++, bit <<= 1) { | |||||
| 190 | char name[100]; | |||||
| 191 | ||||||
| 192 | if (named & bit) { | |||||
| 193 | if (nRead += XkmGetCountedString(file, name, 100)) { | |||||
| 194 | xkb->names->vmods[i] = XkbInternAtom(xkb->dpy, name, False0); | |||||
| 195 | if (changes) | |||||
| 196 | changes->names.changed_vmods |= bit; | |||||
| 197 | } | |||||
| 198 | } | |||||
| 199 | } | |||||
| 200 | return nRead; | |||||
| 201 | } | |||||
| 202 | ||||||
| 203 | /***====================================================================***/ | |||||
| 204 | ||||||
| 205 | static int | |||||
| 206 | ReadXkmKeycodes(FILE *file, XkbFileInfo *result, XkbChangesPtr changes) | |||||
| 207 | { | |||||
| 208 | register int i; | |||||
| 209 | unsigned minKC, maxKC, nAl; | |||||
| 210 | int nRead = 0; | |||||
| 211 | char name[100]; | |||||
| 212 | XkbKeyNamePtr pN; | |||||
| 213 | XkbDescPtr xkb; | |||||
| 214 | ||||||
| 215 | xkb = result->xkb; | |||||
| 216 | name[0] = '\0'; | |||||
| 217 | nRead += XkmGetCountedString(file, name, 100); | |||||
| 218 | minKC = XkmGetCARD8(file, &nRead); | |||||
| 219 | maxKC = XkmGetCARD8(file, &nRead); | |||||
| 220 | if (xkb->min_key_code == 0) { | |||||
| 221 | xkb->min_key_code = minKC; | |||||
| 222 | xkb->max_key_code = maxKC; | |||||
| 223 | } | |||||
| 224 | else { | |||||
| 225 | if (minKC < xkb->min_key_code) | |||||
| 226 | xkb->min_key_code = minKC; | |||||
| 227 | if (maxKC > xkb->max_key_code) { | |||||
| 228 | _XkbLibError(_XkbErrBadValue, "ReadXkmKeycodes", maxKC){ _XkbErrCode= (16); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (maxKC); }; | |||||
| 229 | return -1; | |||||
| 230 | } | |||||
| 231 | } | |||||
| 232 | nAl = XkmGetCARD8(file, &nRead); | |||||
| 233 | nRead += XkmSkipPadding(file, 1); | |||||
| 234 | ||||||
| 235 | #define WANTED((1<<0)|(1<<9)|(1<<10)) (XkbKeycodesNameMask(1<<0)|XkbKeyNamesMask(1<<9)|XkbKeyAliasesMask(1<<10)) | |||||
| 236 | if (XkbAllocNames(xkb, WANTED((1<<0)|(1<<9)|(1<<10)), 0, nAl) != Success0) { | |||||
| 237 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmKeycodes", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 238 | return -1; | |||||
| 239 | } | |||||
| 240 | if (name[0] != '\0') { | |||||
| 241 | xkb->names->keycodes = XkbInternAtom(xkb->dpy, name, False0); | |||||
| 242 | } | |||||
| 243 | ||||||
| 244 | for (pN = &xkb->names->keys[minKC], i = minKC; i <= (int) maxKC; i++, pN++) { | |||||
| 245 | if (fread(pN, 1, XkbKeyNameLength4, file) != XkbKeyNameLength4) { | |||||
| 246 | _XkbLibError(_XkbErrBadLength, "ReadXkmKeycodes", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 247 | return -1; | |||||
| 248 | } | |||||
| 249 | nRead += XkbKeyNameLength4; | |||||
| 250 | } | |||||
| 251 | if (nAl > 0) { | |||||
| 252 | XkbKeyAliasPtr pAl; | |||||
| 253 | ||||||
| 254 | for (pAl = xkb->names->key_aliases, i = 0; i < nAl; i++, pAl++) { | |||||
| 255 | int tmp; | |||||
| 256 | ||||||
| 257 | tmp = fread(pAl, 1, 2 * XkbKeyNameLength4, file); | |||||
| 258 | if (tmp != 2 * XkbKeyNameLength4) { | |||||
| 259 | _XkbLibError(_XkbErrBadLength, "ReadXkmKeycodes", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 260 | return -1; | |||||
| 261 | } | |||||
| 262 | nRead += 2 * XkbKeyNameLength4; | |||||
| 263 | } | |||||
| 264 | if (changes) | |||||
| 265 | changes->names.changed |= XkbKeyAliasesMask(1<<10); | |||||
| 266 | } | |||||
| 267 | if (changes) | |||||
| 268 | changes->names.changed |= XkbKeyNamesMask(1<<9); | |||||
| 269 | return nRead; | |||||
| 270 | } | |||||
| 271 | ||||||
| 272 | /***====================================================================***/ | |||||
| 273 | ||||||
| 274 | static int | |||||
| 275 | ReadXkmKeyTypes(FILE *file, XkbFileInfo *result, XkbChangesPtr changes) | |||||
| 276 | { | |||||
| 277 | register unsigned i, n; | |||||
| 278 | unsigned num_types; | |||||
| 279 | int nRead = 0; | |||||
| 280 | int tmp; | |||||
| 281 | XkbKeyTypePtr type; | |||||
| 282 | xkmKeyTypeDesc wire; | |||||
| 283 | XkbKTMapEntryPtr entry; | |||||
| 284 | xkmKTMapEntryDesc wire_entry; | |||||
| 285 | char buf[100]; | |||||
| 286 | XkbDescPtr xkb; | |||||
| 287 | ||||||
| 288 | xkb = result->xkb; | |||||
| 289 | if ((tmp = XkmGetCountedString(file, buf, 100)) < 1) { | |||||
| 290 | _XkbLibError(_XkbErrBadLength, "ReadXkmKeyTypes", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 291 | return -1; | |||||
| 292 | } | |||||
| 293 | nRead += tmp; | |||||
| 294 | if (buf[0] != '\0') { | |||||
| 295 | if (XkbAllocNames(xkb, XkbTypesNameMask(1<<4), 0, 0) != Success0) { | |||||
| 296 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmKeyTypes", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 297 | return -1; | |||||
| 298 | } | |||||
| 299 | xkb->names->types = XkbInternAtom(xkb->dpy, buf, False0); | |||||
| 300 | } | |||||
| 301 | num_types = XkmGetCARD16(file, &nRead); | |||||
| 302 | nRead += XkmSkipPadding(file, 2); | |||||
| 303 | if (num_types < 1) | |||||
| 304 | return nRead; | |||||
| 305 | if (XkbAllocClientMap(xkb, XkbKeyTypesMask(1<<0), num_types) != Success0) { | |||||
| 306 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmKeyTypes", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 307 | return nRead; | |||||
| 308 | } | |||||
| 309 | xkb->map->num_types = num_types; | |||||
| 310 | if (num_types < XkbNumRequiredTypes(3 +1)) { | |||||
| 311 | _XkbLibError(_XkbErrMissingReqTypes, "ReadXkmKeyTypes", 0){ _XkbErrCode= (3); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 312 | return -1; | |||||
| 313 | } | |||||
| 314 | type = xkb->map->types; | |||||
| 315 | for (i = 0; i < num_types; i++, type++) { | |||||
| 316 | if ((int) fread(&wire, SIZEOF(xkmKeyTypeDesc)8, 1, file) < 1) { | |||||
| 317 | _XkbLibError(_XkbErrBadLength, "ReadXkmKeyTypes", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 318 | return -1; | |||||
| 319 | } | |||||
| 320 | nRead += SIZEOF(xkmKeyTypeDesc)8; | |||||
| 321 | if (((i == XkbOneLevelIndex0) && (wire.numLevels != 1)) || | |||||
| 322 | (((i == XkbTwoLevelIndex1) || (i == XkbAlphabeticIndex2) || | |||||
| 323 | ((i) == XkbKeypadIndex3)) && (wire.numLevels != 2))) { | |||||
| 324 | _XkbLibError(_XkbErrBadTypeWidth, "ReadXkmKeyTypes", i){ _XkbErrCode= (19); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (i); }; | |||||
| 325 | return -1; | |||||
| 326 | } | |||||
| 327 | tmp = wire.nMapEntries; | |||||
| 328 | XkmInsureTypedSize(type->map, type->map_count, &tmp, XkbKTMapEntryRec)((type->map)=((XkbKTMapEntryRec *)XkmInsureSize((char *)(type ->map),(type->map_count),(&tmp),sizeof(XkbKTMapEntryRec )))); | |||||
| 329 | if ((wire.nMapEntries > 0) && (type->map == NULL((void*)0))) { | |||||
| 330 | _XkbLibError(_XkbErrBadValue, "ReadXkmKeyTypes", wire.nMapEntries){ _XkbErrCode= (16); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (wire.nMapEntries); }; | |||||
| 331 | return -1; | |||||
| 332 | } | |||||
| 333 | for (n = 0, entry = type->map; n < wire.nMapEntries; n++, entry++) { | |||||
| 334 | if (fread(&wire_entry, SIZEOF(xkmKTMapEntryDesc)4, 1, file) < | |||||
| 335 | (int) 1) { | |||||
| 336 | _XkbLibError(_XkbErrBadLength, "ReadXkmKeyTypes", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 337 | return -1; | |||||
| 338 | } | |||||
| 339 | nRead += SIZEOF(xkmKTMapEntryDesc)4; | |||||
| 340 | entry->active = (wire_entry.virtualMods == 0); | |||||
| 341 | entry->level = wire_entry.level; | |||||
| 342 | entry->mods.mask = wire_entry.realMods; | |||||
| 343 | entry->mods.real_mods = wire_entry.realMods; | |||||
| 344 | entry->mods.vmods = wire_entry.virtualMods; | |||||
| 345 | } | |||||
| 346 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 347 | if (((i == XkbOneLevelIndex0) && (strcmp(buf, "ONE_LEVEL") != 0)) || | |||||
| 348 | ((i == XkbTwoLevelIndex1) && (strcmp(buf, "TWO_LEVEL") != 0)) || | |||||
| 349 | ((i == XkbAlphabeticIndex2) && (strcmp(buf, "ALPHABETIC") != 0)) || | |||||
| 350 | ((i == XkbKeypadIndex3) && (strcmp(buf, "KEYPAD") != 0))) { | |||||
| 351 | _XkbLibError(_XkbErrBadTypeName, "ReadXkmKeyTypes", 0){ _XkbErrCode= (18); _XkbErrLocation= ("ReadXkmKeyTypes"); _XkbErrData = (0); }; | |||||
| 352 | return -1; | |||||
| 353 | } | |||||
| 354 | if (buf[0] != '\0') { | |||||
| 355 | type->name = XkbInternAtom(xkb->dpy, buf, False0); | |||||
| 356 | } | |||||
| 357 | else | |||||
| 358 | type->name = None0L; | |||||
| 359 | ||||||
| 360 | if (wire.preserve) { | |||||
| 361 | xkmModsDesc p_entry; | |||||
| 362 | XkbModsPtr pre; | |||||
| 363 | ||||||
| 364 | XkmInsureTypedSize(type->preserve, type->map_count, &tmp,((type->preserve)=((XkbModsRec *)XkmInsureSize((char *)(type ->preserve),(type->map_count),(&tmp),sizeof(XkbModsRec )))) | |||||
| 365 | XkbModsRec)((type->preserve)=((XkbModsRec *)XkmInsureSize((char *)(type ->preserve),(type->map_count),(&tmp),sizeof(XkbModsRec )))); | |||||
| 366 | if (type->preserve == NULL((void*)0)) { | |||||
| 367 | _XkbLibError(_XkbErrBadMatch, "ReadXkmKeycodes", 0){ _XkbErrCode= (17); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 368 | return -1; | |||||
| 369 | } | |||||
| 370 | for (n = 0, pre = type->preserve; n < wire.nMapEntries; n++, pre++) { | |||||
| 371 | if (fread(&p_entry, SIZEOF(xkmModsDesc)4, 1, file) < 1) { | |||||
| 372 | _XkbLibError(_XkbErrBadLength, "ReadXkmKeycodes", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 373 | return -1; | |||||
| 374 | } | |||||
| 375 | nRead += SIZEOF(xkmModsDesc)4; | |||||
| 376 | pre->mask = p_entry.realMods; | |||||
| 377 | pre->real_mods = p_entry.realMods; | |||||
| 378 | pre->vmods = p_entry.virtualMods; | |||||
| 379 | } | |||||
| 380 | } | |||||
| 381 | if (wire.nLevelNames > 0) { | |||||
| 382 | int width = wire.numLevels; | |||||
| 383 | ||||||
| 384 | if (wire.nLevelNames > (unsigned) width) { | |||||
| 385 | _XkbLibError(_XkbErrBadMatch, "ReadXkmKeycodes", 0){ _XkbErrCode= (17); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 386 | return -1; | |||||
| 387 | } | |||||
| 388 | XkmInsureTypedSize(type->level_names, type->num_levels, &width,((type->level_names)=((Atom *)XkmInsureSize((char *)(type-> level_names),(type->num_levels),(&width),sizeof(Atom)) )) | |||||
| 389 | Atom)((type->level_names)=((Atom *)XkmInsureSize((char *)(type-> level_names),(type->num_levels),(&width),sizeof(Atom)) )); | |||||
| 390 | if (type->level_names != NULL((void*)0)) { | |||||
| 391 | for (n = 0; n < wire.nLevelNames; n++) { | |||||
| 392 | if ((tmp = XkmGetCountedString(file, buf, 100)) < 1) | |||||
| 393 | return -1; | |||||
| 394 | nRead += tmp; | |||||
| 395 | if (strlen(buf) == 0) | |||||
| 396 | type->level_names[n] = None0L; | |||||
| 397 | else | |||||
| 398 | type->level_names[n] = XkbInternAtom(xkb->dpy, buf, 0); | |||||
| 399 | } | |||||
| 400 | } | |||||
| 401 | } | |||||
| 402 | type->mods.mask = wire.realMods; | |||||
| 403 | type->mods.real_mods = wire.realMods; | |||||
| 404 | type->mods.vmods = wire.virtualMods; | |||||
| 405 | type->num_levels = wire.numLevels; | |||||
| 406 | type->map_count = wire.nMapEntries; | |||||
| 407 | } | |||||
| 408 | if (changes) { | |||||
| 409 | changes->map.changed |= XkbKeyTypesMask(1<<0); | |||||
| 410 | changes->map.first_type = 0; | |||||
| 411 | changes->map.num_types = xkb->map->num_types; | |||||
| 412 | } | |||||
| 413 | return nRead; | |||||
| 414 | } | |||||
| 415 | ||||||
| 416 | /***====================================================================***/ | |||||
| 417 | ||||||
| 418 | static int | |||||
| 419 | ReadXkmCompatMap(FILE *file, XkbFileInfo *result, XkbChangesPtr changes) | |||||
| 420 | { | |||||
| 421 | register int i; | |||||
| 422 | unsigned num_si, groups; | |||||
| 423 | char name[100]; | |||||
| 424 | XkbSymInterpretPtr interp; | |||||
| 425 | xkmSymInterpretDesc wire; | |||||
| 426 | unsigned tmp; | |||||
| 427 | int nRead = 0; | |||||
| 428 | XkbDescPtr xkb; | |||||
| 429 | XkbCompatMapPtr compat; | |||||
| 430 | ||||||
| 431 | xkb = result->xkb; | |||||
| 432 | if ((tmp = XkmGetCountedString(file, name, 100)) < 1) { | |||||
| 433 | _XkbLibError(_XkbErrBadLength, "ReadXkmCompatMap", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmCompatMap"); _XkbErrData = (0); }; | |||||
| 434 | return -1; | |||||
| 435 | } | |||||
| 436 | nRead += tmp; | |||||
| 437 | if (name[0] != '\0') { | |||||
| 438 | if (XkbAllocNames(xkb, XkbCompatNameMask(1<<5), 0, 0) != Success0) { | |||||
| 439 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmCompatMap", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmCompatMap"); _XkbErrData = (0); }; | |||||
| 440 | return -1; | |||||
| 441 | } | |||||
| 442 | xkb->names->compat = XkbInternAtom(xkb->dpy, name, False0); | |||||
| 443 | } | |||||
| 444 | num_si = XkmGetCARD16(file, &nRead); | |||||
| 445 | groups = XkmGetCARD8(file, &nRead); | |||||
| 446 | nRead += XkmSkipPadding(file, 1); | |||||
| 447 | if (XkbAllocCompatMap(xkb, XkbAllCompatMask(0x3), num_si) != Success0) | |||||
| 448 | return -1; | |||||
| 449 | compat = xkb->compat; | |||||
| 450 | compat->num_si = num_si; | |||||
| 451 | interp = compat->sym_interpret; | |||||
| 452 | for (i = 0; i < num_si; i++, interp++) { | |||||
| 453 | tmp = fread(&wire, SIZEOF(xkmSymInterpretDesc)16, 1, file); | |||||
| 454 | nRead += tmp * SIZEOF(xkmSymInterpretDesc)16; | |||||
| 455 | interp->sym = wire.sym; | |||||
| 456 | interp->mods = wire.mods; | |||||
| 457 | interp->match = wire.match; | |||||
| 458 | interp->virtual_mod = wire.virtualMod; | |||||
| 459 | interp->flags = wire.flags; | |||||
| 460 | interp->act.type = wire.actionType; | |||||
| 461 | interp->act.data[0] = wire.actionData[0]; | |||||
| 462 | interp->act.data[1] = wire.actionData[1]; | |||||
| 463 | interp->act.data[2] = wire.actionData[2]; | |||||
| 464 | interp->act.data[3] = wire.actionData[3]; | |||||
| 465 | interp->act.data[4] = wire.actionData[4]; | |||||
| 466 | interp->act.data[5] = wire.actionData[5]; | |||||
| 467 | interp->act.data[6] = wire.actionData[6]; | |||||
| 468 | } | |||||
| 469 | if ((num_si > 0) && (changes)) { | |||||
| 470 | changes->compat.first_si = 0; | |||||
| 471 | changes->compat.num_si = num_si; | |||||
| 472 | } | |||||
| 473 | if (groups) { | |||||
| 474 | register unsigned bit; | |||||
| 475 | ||||||
| 476 | for (i = 0, bit = 1; i < XkbNumKbdGroups4; i++, bit <<= 1) { | |||||
| 477 | xkmModsDesc md; | |||||
| 478 | ||||||
| 479 | if (groups & bit) { | |||||
| 480 | tmp = fread(&md, SIZEOF(xkmModsDesc)4, 1, file); | |||||
| 481 | nRead += tmp * SIZEOF(xkmModsDesc)4; | |||||
| 482 | xkb->compat->groups[i].real_mods = md.realMods; | |||||
| 483 | xkb->compat->groups[i].vmods = md.virtualMods; | |||||
| 484 | if (md.virtualMods != 0) { | |||||
| 485 | unsigned mask; | |||||
| 486 | ||||||
| 487 | if (XkbVirtualModsToReal(xkb, md.virtualMods, &mask)) | |||||
| 488 | xkb->compat->groups[i].mask = md.realMods | mask; | |||||
| 489 | } | |||||
| 490 | else | |||||
| 491 | xkb->compat->groups[i].mask = md.realMods; | |||||
| 492 | } | |||||
| 493 | } | |||||
| 494 | if (changes) | |||||
| 495 | changes->compat.changed_groups |= groups; | |||||
| 496 | } | |||||
| 497 | return nRead; | |||||
| 498 | } | |||||
| 499 | ||||||
| 500 | static int | |||||
| 501 | ReadXkmIndicators(FILE *file, XkbFileInfo *result, XkbChangesPtr changes) | |||||
| 502 | { | |||||
| 503 | register unsigned nLEDs; | |||||
| 504 | xkmIndicatorMapDesc wire; | |||||
| 505 | char buf[100]; | |||||
| 506 | unsigned tmp; | |||||
| 507 | int nRead = 0; | |||||
| 508 | XkbDescPtr xkb; | |||||
| 509 | ||||||
| 510 | xkb = result->xkb; | |||||
| 511 | if ((xkb->indicators == NULL((void*)0)) && (XkbAllocIndicatorMaps(xkb) != Success0)) { | |||||
| 512 | _XkbLibError(_XkbErrBadAlloc, "indicator rec", 0){ _XkbErrCode= (23); _XkbErrLocation= ("indicator rec"); _XkbErrData = (0); }; | |||||
| 513 | return -1; | |||||
| 514 | } | |||||
| 515 | if (XkbAllocNames(xkb, XkbIndicatorNamesMask(1<<8), 0, 0) != Success0) { | |||||
| 516 | _XkbLibError(_XkbErrBadAlloc, "indicator names", 0){ _XkbErrCode= (23); _XkbErrLocation= ("indicator names"); _XkbErrData = (0); }; | |||||
| 517 | return -1; | |||||
| 518 | } | |||||
| 519 | nLEDs = XkmGetCARD8(file, &nRead); | |||||
| 520 | nRead += XkmSkipPadding(file, 3); | |||||
| 521 | xkb->indicators->phys_indicators = XkmGetCARD32(file, &nRead); | |||||
| 522 | while (nLEDs-- > 0) { | |||||
| 523 | Atom name; | |||||
| 524 | XkbIndicatorMapPtr map; | |||||
| 525 | ||||||
| 526 | if ((tmp = XkmGetCountedString(file, buf, 100)) < 1) { | |||||
| 527 | _XkbLibError(_XkbErrBadLength, "ReadXkmIndicators", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmIndicators"); _XkbErrData = (0); }; | |||||
| 528 | return -1; | |||||
| 529 | } | |||||
| 530 | nRead += tmp; | |||||
| 531 | if (buf[0] != '\0') | |||||
| 532 | name = XkbInternAtom(xkb->dpy, buf, False0); | |||||
| 533 | else | |||||
| 534 | name = None0L; | |||||
| 535 | if ((tmp = fread(&wire, SIZEOF(xkmIndicatorMapDesc)12, 1, file)) < 1) { | |||||
| 536 | _XkbLibError(_XkbErrBadLength, "ReadXkmIndicators", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmIndicators"); _XkbErrData = (0); }; | |||||
| 537 | return -1; | |||||
| 538 | } | |||||
| 539 | nRead += tmp * SIZEOF(xkmIndicatorMapDesc)12; | |||||
| 540 | if (xkb->names) { | |||||
| 541 | xkb->names->indicators[wire.indicator - 1] = name; | |||||
| 542 | if (changes) | |||||
| 543 | changes->names.changed_indicators |= | |||||
| 544 | (1 << (wire.indicator - 1)); | |||||
| 545 | } | |||||
| 546 | map = &xkb->indicators->maps[wire.indicator - 1]; | |||||
| 547 | map->flags = wire.flags; | |||||
| 548 | map->which_groups = wire.which_groups; | |||||
| 549 | map->groups = wire.groups; | |||||
| 550 | map->which_mods = wire.which_mods; | |||||
| 551 | map->mods.mask = wire.real_mods; | |||||
| 552 | map->mods.real_mods = wire.real_mods; | |||||
| 553 | map->mods.vmods = wire.vmods; | |||||
| 554 | map->ctrls = wire.ctrls; | |||||
| 555 | } | |||||
| 556 | return nRead; | |||||
| 557 | } | |||||
| 558 | ||||||
| 559 | static XkbKeyTypePtr | |||||
| 560 | FindTypeForKey(XkbDescPtr xkb, Atom name, unsigned width, KeySym *syms) | |||||
| 561 | { | |||||
| 562 | if ((!xkb) || (!xkb->map)) | |||||
| 563 | return NULL((void*)0); | |||||
| 564 | if (name != None0L) { | |||||
| 565 | register unsigned i; | |||||
| 566 | ||||||
| 567 | for (i = 0; i < xkb->map->num_types; i++) { | |||||
| 568 | if (xkb->map->types[i].name == name) { | |||||
| 569 | #ifdef DEBUG | |||||
| 570 | if (xkb->map->types[i].num_levels != width) | |||||
| 571 | fprintf(stderr__stderrp, | |||||
| 572 | "Group width mismatch between key and type\n"); | |||||
| 573 | #endif | |||||
| 574 | return &xkb->map->types[i]; | |||||
| 575 | } | |||||
| 576 | } | |||||
| 577 | } | |||||
| 578 | if ((width < 2) || ((syms != NULL((void*)0)) && (syms[1] == NoSymbol0L))) | |||||
| 579 | return &xkb->map->types[XkbOneLevelIndex0]; | |||||
| 580 | if (syms != NULL((void*)0)) { | |||||
| 581 | if (XkbKSIsLower(syms[0])(_XkbKSCheckCase(syms[0])&(1<<0)) && XkbKSIsUpper(syms[1])(_XkbKSCheckCase(syms[1])&(1<<1))) | |||||
| 582 | return &xkb->map->types[XkbAlphabeticIndex2]; | |||||
| 583 | else if (XkbKSIsKeypad(syms[0])(((syms[0])>=0xff80)&&((syms[0])<=0xffbd)) || XkbKSIsKeypad(syms[1])(((syms[1])>=0xff80)&&((syms[1])<=0xffbd))) | |||||
| 584 | return &xkb->map->types[XkbKeypadIndex3]; | |||||
| 585 | } | |||||
| 586 | return &xkb->map->types[XkbTwoLevelIndex1]; | |||||
| 587 | } | |||||
| 588 | ||||||
| 589 | static int | |||||
| 590 | ReadXkmSymbols(FILE *file, XkbFileInfo *result) | |||||
| 591 | { | |||||
| 592 | register int i, g, s, totalVModMaps; | |||||
| 593 | xkmKeySymMapDesc wireMap; | |||||
| 594 | char buf[100]; | |||||
| 595 | unsigned minKC, maxKC, groupNames, tmp; | |||||
| 596 | int nRead = 0; | |||||
| 597 | XkbDescPtr xkb; | |||||
| 598 | ||||||
| 599 | xkb = result->xkb; | |||||
| 600 | if ((tmp = XkmGetCountedString(file, buf, 100)) < 1) | |||||
| 601 | return -1; | |||||
| 602 | nRead += tmp; | |||||
| 603 | minKC = XkmGetCARD8(file, &nRead); | |||||
| 604 | maxKC = XkmGetCARD8(file, &nRead); | |||||
| 605 | groupNames = XkmGetCARD8(file, &nRead); | |||||
| 606 | totalVModMaps = XkmGetCARD8(file, &nRead); | |||||
| 607 | if (XkbAllocNames(xkb, | |||||
| 608 | XkbSymbolsNameMask(1<<2) | XkbPhysSymbolsNameMask(1<<3) | | |||||
| 609 | XkbGroupNamesMask(1<<12), 0, 0) != Success0) { | |||||
| 610 | _XkbLibError(_XkbErrBadAlloc, "physical names", 0){ _XkbErrCode= (23); _XkbErrLocation= ("physical names"); _XkbErrData = (0); }; | |||||
| 611 | return -1; | |||||
| 612 | } | |||||
| 613 | if ((buf[0] != '\0') && (xkb->names)) { | |||||
| 614 | Atom name; | |||||
| 615 | ||||||
| 616 | name = XkbInternAtom(xkb->dpy, buf, 0); | |||||
| 617 | xkb->names->symbols = name; | |||||
| 618 | xkb->names->phys_symbols = name; | |||||
| 619 | } | |||||
| 620 | for (i = 0, g = 1; i < XkbNumKbdGroups4; i++, g <<= 1) { | |||||
| 621 | if (groupNames & g) { | |||||
| 622 | if ((tmp = XkmGetCountedString(file, buf, 100)) < 1) | |||||
| 623 | return -1; | |||||
| 624 | nRead += tmp; | |||||
| 625 | if ((buf[0] != '\0') && (xkb->names)) { | |||||
| 626 | Atom name; | |||||
| 627 | ||||||
| 628 | name = XkbInternAtom(xkb->dpy, buf, 0); | |||||
| 629 | xkb->names->groups[i] = name; | |||||
| 630 | } | |||||
| 631 | else | |||||
| 632 | xkb->names->groups[i] = None0L; | |||||
| 633 | } | |||||
| 634 | } | |||||
| 635 | if (XkbAllocServerMap(xkb, XkbAllServerInfoMask((1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<< 7)), 0) != Success0) { | |||||
| 636 | _XkbLibError(_XkbErrBadAlloc, "server map", 0){ _XkbErrCode= (23); _XkbErrLocation= ("server map"); _XkbErrData = (0); }; | |||||
| 637 | return -1; | |||||
| 638 | } | |||||
| 639 | if (XkbAllocClientMap(xkb, XkbAllClientInfoMask((1<<0)|(1<<1)|(1<<2)), 0) != Success0) { | |||||
| 640 | _XkbLibError(_XkbErrBadAlloc, "client map", 0){ _XkbErrCode= (23); _XkbErrLocation= ("client map"); _XkbErrData = (0); }; | |||||
| 641 | return -1; | |||||
| 642 | } | |||||
| 643 | if (XkbAllocControls(xkb, XkbAllControlsMask(0xF8001FFF)) != Success0) { | |||||
| 644 | _XkbLibError(_XkbErrBadAlloc, "controls", 0){ _XkbErrCode= (23); _XkbErrLocation= ("controls"); _XkbErrData = (0); }; | |||||
| 645 | return -1; | |||||
| 646 | } | |||||
| 647 | if ((xkb->map == NULL((void*)0)) || (xkb->server == NULL((void*)0))) | |||||
| 648 | return -1; | |||||
| 649 | if (xkb->min_key_code < 8) | |||||
| 650 | xkb->min_key_code = minKC; | |||||
| 651 | if (xkb->max_key_code < 8) | |||||
| 652 | xkb->max_key_code = maxKC; | |||||
| 653 | if ((minKC >= 8) && (minKC < xkb->min_key_code)) | |||||
| 654 | xkb->min_key_code = minKC; | |||||
| 655 | if ((maxKC >= 8) && (maxKC > xkb->max_key_code)) { | |||||
| 656 | _XkbLibError(_XkbErrBadValue, "keys in symbol map", maxKC){ _XkbErrCode= (16); _XkbErrLocation= ("keys in symbol map"); _XkbErrData= (maxKC); }; | |||||
| 657 | return -1; | |||||
| 658 | } | |||||
| 659 | for (i = minKC; i <= (int) maxKC; i++) { | |||||
| 660 | Atom typeName[XkbNumKbdGroups4]; | |||||
| 661 | XkbKeyTypePtr type[XkbNumKbdGroups4]; | |||||
| 662 | ||||||
| 663 | if ((tmp = fread(&wireMap, SIZEOF(xkmKeySymMapDesc)4, 1, file)) < 1) { | |||||
| 664 | _XkbLibError(_XkbErrBadLength, "ReadXkmSymbols", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmSymbols"); _XkbErrData = (0); }; | |||||
| 665 | return -1; | |||||
| 666 | } | |||||
| 667 | nRead += tmp * SIZEOF(xkmKeySymMapDesc)4; | |||||
| 668 | bzero((char *) typeName, XkbNumKbdGroups * sizeof(Atom))__builtin___memset_chk ((char *) typeName, 0, 4 * sizeof(Atom ), __builtin_object_size ((char *) typeName, 0)); | |||||
| 669 | bzero((char *) type, XkbNumKbdGroups * sizeof(XkbKeyTypePtr))__builtin___memset_chk ((char *) type, 0, 4 * sizeof(XkbKeyTypePtr ), __builtin_object_size ((char *) type, 0)); | |||||
| 670 | if (wireMap.flags & XkmKeyHasTypes(0x0f)) { | |||||
| 671 | register int g; | |||||
| 672 | ||||||
| 673 | for (g = 0; g < XkbNumKbdGroups4; g++) { | |||||
| 674 | if ((wireMap.flags & (1 << g)) && | |||||
| 675 | ((tmp = XkmGetCountedString(file, buf, 100)) > 0)) { | |||||
| 676 | typeName[g] = XkbInternAtom(xkb->dpy, buf, 1); | |||||
| 677 | nRead += tmp; | |||||
| 678 | } | |||||
| 679 | type[g] = FindTypeForKey(xkb, typeName[g], wireMap.width, NULL((void*)0)); | |||||
| 680 | if (type[g] == NULL((void*)0)) { | |||||
| 681 | _XkbLibError(_XkbErrMissingTypes, "ReadXkmSymbols", 0){ _XkbErrCode= (2); _XkbErrLocation= ("ReadXkmSymbols"); _XkbErrData = (0); }; | |||||
| 682 | return -1; | |||||
| 683 | } | |||||
| 684 | if (typeName[g] == type[g]->name) | |||||
| 685 | xkb->server->explicit[i] |= (1 << g); | |||||
| 686 | } | |||||
| 687 | } | |||||
| 688 | if (wireMap.flags & XkmRepeatingKey(1<<6)) { | |||||
| 689 | xkb->ctrls->per_key_repeat[i / 8] |= (1 << (i % 8)); | |||||
| 690 | xkb->server->explicit[i] |= XkbExplicitAutoRepeatMask(1<<5); | |||||
| 691 | } | |||||
| 692 | else if (wireMap.flags & XkmNonRepeatingKey(1<<7)) { | |||||
| 693 | xkb->ctrls->per_key_repeat[i / 8] &= ~(1 << (i % 8)); | |||||
| 694 | xkb->server->explicit[i] |= XkbExplicitAutoRepeatMask(1<<5); | |||||
| 695 | } | |||||
| 696 | xkb->map->modmap[i] = wireMap.modifier_map; | |||||
| 697 | if (XkbNumGroups(wireMap.num_groups)((wireMap.num_groups)&0x0f) > 0) { | |||||
| 698 | KeySym *sym; | |||||
| 699 | int nSyms; | |||||
| 700 | ||||||
| 701 | if (XkbNumGroups(wireMap.num_groups)((wireMap.num_groups)&0x0f) > xkb->ctrls->num_groups) | |||||
| 702 | xkb->ctrls->num_groups = wireMap.num_groups; | |||||
| 703 | nSyms = XkbNumGroups(wireMap.num_groups)((wireMap.num_groups)&0x0f) * wireMap.width; | |||||
| 704 | sym = XkbResizeKeySyms(xkb, i, nSyms); | |||||
| 705 | if (!sym) | |||||
| 706 | return -1; | |||||
| 707 | for (s = 0; s < nSyms; s++) { | |||||
| 708 | *sym++ = XkmGetCARD32(file, &nRead); | |||||
| 709 | } | |||||
| 710 | if (wireMap.flags & XkmKeyHasActions(1<<4)) { | |||||
| 711 | XkbAction *act; | |||||
| 712 | ||||||
| 713 | act = XkbResizeKeyActions(xkb, i, nSyms); | |||||
| 714 | for (s = 0; s < nSyms; s++, act++) { | |||||
| 715 | tmp = fread(act, SIZEOF(xkmActionDesc)8, 1, file); | |||||
| 716 | nRead += tmp * SIZEOF(xkmActionDesc)8; | |||||
| 717 | } | |||||
| 718 | xkb->server->explicit[i] |= XkbExplicitInterpretMask(1<<4); | |||||
| 719 | } | |||||
| 720 | } | |||||
| 721 | for (g = 0; g < XkbNumGroups(wireMap.num_groups)((wireMap.num_groups)&0x0f); g++) { | |||||
| 722 | if (((xkb->server->explicit[i] & (1 << g)) == 0) || | |||||
| 723 | (type[g] == NULL((void*)0))) { | |||||
| 724 | KeySym *tmpSyms; | |||||
| 725 | ||||||
| 726 | tmpSyms = XkbKeySymsPtr(xkb, i)((&((xkb)->map)->syms[(((xkb)->map)->key_sym_map [(i)].offset)])) + (wireMap.width * g); | |||||
| 727 | type[g] = FindTypeForKey(xkb, None0L, wireMap.width, tmpSyms); | |||||
| 728 | } | |||||
| 729 | xkb->map->key_sym_map[i].kt_index[g] = | |||||
| 730 | type[g] - (&xkb->map->types[0]); | |||||
| 731 | } | |||||
| 732 | xkb->map->key_sym_map[i].group_info = wireMap.num_groups; | |||||
| 733 | xkb->map->key_sym_map[i].width = wireMap.width; | |||||
| 734 | if (wireMap.flags & XkmKeyHasBehavior(1<<5)) { | |||||
| 735 | xkmBehaviorDesc b; | |||||
| 736 | ||||||
| 737 | tmp = fread(&b, SIZEOF(xkmBehaviorDesc)4, 1, file); | |||||
| 738 | nRead += tmp * SIZEOF(xkmBehaviorDesc)4; | |||||
| 739 | xkb->server->behaviors[i].type = b.type; | |||||
| 740 | xkb->server->behaviors[i].data = b.data; | |||||
| 741 | xkb->server->explicit[i] |= XkbExplicitBehaviorMask(1<<6); | |||||
| 742 | } | |||||
| 743 | } | |||||
| 744 | if (totalVModMaps > 0) { | |||||
| 745 | xkmVModMapDesc v; | |||||
| 746 | ||||||
| 747 | for (i = 0; i < totalVModMaps; i++) { | |||||
| 748 | tmp = fread(&v, SIZEOF(xkmVModMapDesc)4, 1, file); | |||||
| 749 | nRead += tmp * SIZEOF(xkmVModMapDesc)4; | |||||
| 750 | if (tmp > 0) | |||||
| 751 | xkb->server->vmodmap[v.key] = v.vmods; | |||||
| 752 | } | |||||
| 753 | } | |||||
| 754 | return nRead; | |||||
| 755 | } | |||||
| 756 | ||||||
| 757 | static int | |||||
| 758 | ReadXkmGeomDoodad(FILE *file, Display *dpy, | |||||
| 759 | XkbGeometryPtr geom, XkbSectionPtr section) | |||||
| 760 | { | |||||
| 761 | XkbDoodadPtr doodad; | |||||
| 762 | xkmDoodadDesc doodadWire; | |||||
| 763 | char buf[100]; | |||||
| 764 | unsigned tmp; | |||||
| 765 | int nRead = 0; | |||||
| 766 | ||||||
| 767 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 768 | tmp = fread(&doodadWire, SIZEOF(xkmDoodadDesc)16, 1, file); | |||||
| 769 | nRead += SIZEOF(xkmDoodadDesc)16 * tmp; | |||||
| 770 | doodad = XkbAddGeomDoodad(geom, section, XkbInternAtom(dpy, buf, False0)); | |||||
| 771 | if (!doodad) | |||||
| 772 | return nRead; | |||||
| 773 | doodad->any.type = doodadWire.any.type; | |||||
| 774 | doodad->any.priority = doodadWire.any.priority; | |||||
| 775 | doodad->any.top = doodadWire.any.top; | |||||
| 776 | doodad->any.left = doodadWire.any.left; | |||||
| 777 | switch (doodadWire.any.type) { | |||||
| 778 | case XkbOutlineDoodad1: | |||||
| 779 | case XkbSolidDoodad2: | |||||
| 780 | doodad->shape.angle = doodadWire.shape.angle; | |||||
| 781 | doodad->shape.color_ndx = doodadWire.shape.color_ndx; | |||||
| 782 | doodad->shape.shape_ndx = doodadWire.shape.shape_ndx; | |||||
| 783 | break; | |||||
| 784 | case XkbTextDoodad3: | |||||
| 785 | doodad->text.angle = doodadWire.text.angle; | |||||
| 786 | doodad->text.width = doodadWire.text.width; | |||||
| 787 | doodad->text.height = doodadWire.text.height; | |||||
| 788 | doodad->text.color_ndx = doodadWire.text.color_ndx; | |||||
| 789 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 790 | doodad->text.text = _XkbDupString(buf); | |||||
| 791 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 792 | doodad->text.font = _XkbDupString(buf); | |||||
| 793 | break; | |||||
| 794 | case XkbIndicatorDoodad4: | |||||
| 795 | doodad->indicator.shape_ndx = doodadWire.indicator.shape_ndx; | |||||
| 796 | doodad->indicator.on_color_ndx = doodadWire.indicator.on_color_ndx; | |||||
| 797 | doodad->indicator.off_color_ndx = doodadWire.indicator.off_color_ndx; | |||||
| 798 | break; | |||||
| 799 | case XkbLogoDoodad5: | |||||
| 800 | doodad->logo.angle = doodadWire.logo.angle; | |||||
| 801 | doodad->logo.color_ndx = doodadWire.logo.color_ndx; | |||||
| 802 | doodad->logo.shape_ndx = doodadWire.logo.shape_ndx; | |||||
| 803 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 804 | doodad->logo.logo_name = _XkbDupString(buf); | |||||
| 805 | break; | |||||
| 806 | default: | |||||
| 807 | /* report error? */ | |||||
| 808 | return nRead; | |||||
| 809 | } | |||||
| 810 | return nRead; | |||||
| 811 | } | |||||
| 812 | ||||||
| 813 | static int | |||||
| 814 | ReadXkmGeomOverlay(FILE *file, Display *dpy, | |||||
| 815 | XkbGeometryPtr geom, XkbSectionPtr section) | |||||
| 816 | { | |||||
| 817 | char buf[100]; | |||||
| 818 | unsigned tmp; | |||||
| 819 | int nRead = 0; | |||||
| 820 | XkbOverlayPtr ol; | |||||
| 821 | XkbOverlayRowPtr row; | |||||
| 822 | xkmOverlayDesc olWire; | |||||
| 823 | xkmOverlayRowDesc rowWire; | |||||
| 824 | register int r; | |||||
| 825 | ||||||
| 826 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 827 | tmp = fread(&olWire, SIZEOF(xkmOverlayDesc)4, 1, file); | |||||
| 828 | nRead += tmp * SIZEOF(xkmOverlayDesc)4; | |||||
| 829 | ol = XkbAddGeomOverlay(section, XkbInternAtom(dpy, buf, False0), | |||||
| 830 | olWire.num_rows); | |||||
| 831 | if (!ol) | |||||
| 832 | return nRead; | |||||
| 833 | for (r = 0; r < olWire.num_rows; r++) { | |||||
| 834 | int k; | |||||
| 835 | xkmOverlayKeyDesc keyWire; | |||||
| 836 | ||||||
| 837 | tmp = fread(&rowWire, SIZEOF(xkmOverlayRowDesc)4, 1, file); | |||||
| 838 | nRead += tmp * SIZEOF(xkmOverlayRowDesc)4; | |||||
| 839 | row = XkbAddGeomOverlayRow(ol, rowWire.row_under, rowWire.num_keys); | |||||
| 840 | if (!row) { | |||||
| 841 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeomOverlay", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeomOverlay"); _XkbErrData= (0); }; | |||||
| 842 | return nRead; | |||||
| 843 | } | |||||
| 844 | for (k = 0; k < rowWire.num_keys; k++) { | |||||
| 845 | tmp = fread(&keyWire, SIZEOF(xkmOverlayKeyDesc)8, 1, file); | |||||
| 846 | nRead += tmp * SIZEOF(xkmOverlayKeyDesc)8; | |||||
| 847 | memcpy(row->keys[k].over.name, keyWire.over, XkbKeyNameLength)__builtin___memcpy_chk (row->keys[k].over.name, keyWire.over , 4, __builtin_object_size (row->keys[k].over.name, 0)); | |||||
| 848 | memcpy(row->keys[k].under.name, keyWire.under, XkbKeyNameLength)__builtin___memcpy_chk (row->keys[k].under.name, keyWire.under , 4, __builtin_object_size (row->keys[k].under.name, 0)); | |||||
| 849 | } | |||||
| 850 | row->num_keys = rowWire.num_keys; | |||||
| 851 | } | |||||
| 852 | return nRead; | |||||
| 853 | } | |||||
| 854 | ||||||
| 855 | static int | |||||
| 856 | ReadXkmGeomSection(FILE *file, Display *dpy, XkbGeometryPtr geom) | |||||
| 857 | { | |||||
| 858 | register int i; | |||||
| 859 | XkbSectionPtr section; | |||||
| 860 | xkmSectionDesc sectionWire; | |||||
| 861 | unsigned tmp; | |||||
| 862 | int nRead = 0; | |||||
| 863 | char buf[100]; | |||||
| 864 | Atom nameAtom; | |||||
| 865 | ||||||
| 866 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 867 | nameAtom = XkbInternAtom(dpy, buf, False0); | |||||
| 868 | tmp = fread(§ionWire, SIZEOF(xkmSectionDesc)16, 1, file); | |||||
| 869 | nRead += SIZEOF(xkmSectionDesc)16 * tmp; | |||||
| 870 | section = XkbAddGeomSection(geom, nameAtom, sectionWire.num_rows, | |||||
| 871 | sectionWire.num_doodads, | |||||
| 872 | sectionWire.num_overlays); | |||||
| 873 | if (!section) { | |||||
| 874 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeomSection", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeomSection"); _XkbErrData= (0); }; | |||||
| 875 | return nRead; | |||||
| 876 | } | |||||
| 877 | section->top = sectionWire.top; | |||||
| 878 | section->left = sectionWire.left; | |||||
| 879 | section->width = sectionWire.width; | |||||
| 880 | section->height = sectionWire.height; | |||||
| 881 | section->angle = sectionWire.angle; | |||||
| 882 | section->priority = sectionWire.priority; | |||||
| 883 | if (sectionWire.num_rows > 0) { | |||||
| 884 | register int k; | |||||
| 885 | XkbRowPtr row; | |||||
| 886 | xkmRowDesc rowWire; | |||||
| 887 | XkbKeyPtr key; | |||||
| 888 | xkmKeyDesc keyWire; | |||||
| 889 | ||||||
| 890 | for (i = 0; i < sectionWire.num_rows; i++) { | |||||
| 891 | tmp = fread(&rowWire, SIZEOF(xkmRowDesc)8, 1, file); | |||||
| 892 | nRead += SIZEOF(xkmRowDesc)8 * tmp; | |||||
| 893 | row = XkbAddGeomRow(section, rowWire.num_keys); | |||||
| 894 | if (!row) { | |||||
| 895 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmKeycodes", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmKeycodes"); _XkbErrData = (0); }; | |||||
| 896 | return nRead; | |||||
| 897 | } | |||||
| 898 | row->top = rowWire.top; | |||||
| 899 | row->left = rowWire.left; | |||||
| 900 | row->vertical = rowWire.vertical; | |||||
| 901 | for (k = 0; k < rowWire.num_keys; k++) { | |||||
| 902 | tmp = fread(&keyWire, SIZEOF(xkmKeyDesc)8, 1, file); | |||||
| 903 | nRead += SIZEOF(xkmKeyDesc)8 * tmp; | |||||
| 904 | key = XkbAddGeomKey(row); | |||||
| 905 | if (!key) { | |||||
| 906 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeomSection", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeomSection"); _XkbErrData= (0); }; | |||||
| 907 | return nRead; | |||||
| 908 | } | |||||
| 909 | memcpy(key->name.name, keyWire.name, XkbKeyNameLength)__builtin___memcpy_chk (key->name.name, keyWire.name, 4, __builtin_object_size (key->name.name, 0)); | |||||
| 910 | key->gap = keyWire.gap; | |||||
| 911 | key->shape_ndx = keyWire.shape_ndx; | |||||
| 912 | key->color_ndx = keyWire.color_ndx; | |||||
| 913 | } | |||||
| 914 | } | |||||
| 915 | } | |||||
| 916 | if (sectionWire.num_doodads > 0) { | |||||
| 917 | for (i = 0; i < sectionWire.num_doodads; i++) { | |||||
| 918 | tmp = ReadXkmGeomDoodad(file, dpy, geom, section); | |||||
| 919 | nRead += tmp; | |||||
| 920 | if (tmp < 1) | |||||
| 921 | return nRead; | |||||
| 922 | } | |||||
| 923 | } | |||||
| 924 | if (sectionWire.num_overlays > 0) { | |||||
| 925 | for (i = 0; i < sectionWire.num_overlays; i++) { | |||||
| 926 | tmp = ReadXkmGeomOverlay(file, dpy, geom, section); | |||||
| 927 | nRead += tmp; | |||||
| 928 | if (tmp < 1) | |||||
| 929 | return nRead; | |||||
| 930 | } | |||||
| 931 | } | |||||
| 932 | return nRead; | |||||
| 933 | } | |||||
| 934 | ||||||
| 935 | static int | |||||
| 936 | ReadXkmGeometry(FILE *file, XkbFileInfo *result) | |||||
| 937 | { | |||||
| 938 | register int i; | |||||
| 939 | char buf[100]; | |||||
| 940 | unsigned tmp; | |||||
| 941 | int nRead = 0; | |||||
| 942 | xkmGeometryDesc wireGeom; | |||||
| 943 | XkbGeometryPtr geom; | |||||
| 944 | XkbGeometrySizesRec sizes; | |||||
| 945 | ||||||
| 946 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 947 | tmp = fread(&wireGeom, SIZEOF(xkmGeometryDesc)20, 1, file); | |||||
| 948 | nRead += tmp * SIZEOF(xkmGeometryDesc)20; | |||||
| 949 | sizes.which = XkbGeomAllMask(0x3f); | |||||
| 950 | sizes.num_properties = wireGeom.num_properties; | |||||
| 951 | sizes.num_colors = wireGeom.num_colors; | |||||
| 952 | sizes.num_shapes = wireGeom.num_shapes; | |||||
| 953 | sizes.num_sections = wireGeom.num_sections; | |||||
| 954 | sizes.num_doodads = wireGeom.num_doodads; | |||||
| 955 | sizes.num_key_aliases = wireGeom.num_key_aliases; | |||||
| 956 | if (XkbAllocGeometry(result->xkb, &sizes) != Success0) { | |||||
| 957 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeometry", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeometry"); _XkbErrData = (0); }; | |||||
| 958 | return nRead; | |||||
| 959 | } | |||||
| 960 | geom = result->xkb->geom; | |||||
| 961 | geom->name = XkbInternAtom(result->xkb->dpy, buf, False0); | |||||
| 962 | geom->width_mm = wireGeom.width_mm; | |||||
| 963 | geom->height_mm = wireGeom.height_mm; | |||||
| 964 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 965 | geom->label_font = _XkbDupString(buf); | |||||
| 966 | if (wireGeom.num_properties > 0) { | |||||
| 967 | char val[1024]; | |||||
| 968 | ||||||
| 969 | for (i = 0; i < wireGeom.num_properties; i++) { | |||||
| 970 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 971 | nRead += XkmGetCountedString(file, val, 1024); | |||||
| 972 | if (XkbAddGeomProperty(geom, buf, val) == NULL((void*)0)) { | |||||
| 973 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeometry", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeometry"); _XkbErrData = (0); }; | |||||
| 974 | return nRead; | |||||
| 975 | } | |||||
| 976 | } | |||||
| 977 | } | |||||
| 978 | if (wireGeom.num_colors > 0) { | |||||
| 979 | for (i = 0; i < wireGeom.num_colors; i++) { | |||||
| 980 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 981 | if (XkbAddGeomColor(geom, buf, i) == NULL((void*)0)) { | |||||
| 982 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeometry", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeometry"); _XkbErrData = (0); }; | |||||
| 983 | return nRead; | |||||
| 984 | } | |||||
| 985 | } | |||||
| 986 | } | |||||
| 987 | geom->base_color = &geom->colors[wireGeom.base_color_ndx]; | |||||
| 988 | geom->label_color = &geom->colors[wireGeom.label_color_ndx]; | |||||
| 989 | if (wireGeom.num_shapes > 0) { | |||||
| 990 | XkbShapePtr shape; | |||||
| 991 | xkmShapeDesc shapeWire; | |||||
| 992 | Atom nameAtom; | |||||
| 993 | ||||||
| 994 | for (i = 0; i < wireGeom.num_shapes; i++) { | |||||
| 995 | register int n; | |||||
| 996 | XkbOutlinePtr ol; | |||||
| 997 | xkmOutlineDesc olWire; | |||||
| 998 | ||||||
| 999 | nRead += XkmGetCountedString(file, buf, 100); | |||||
| 1000 | nameAtom = XkbInternAtom(result->xkb->dpy, buf, False0); | |||||
| 1001 | tmp = fread(&shapeWire, SIZEOF(xkmShapeDesc)4, 1, file); | |||||
| 1002 | nRead += tmp * SIZEOF(xkmShapeDesc)4; | |||||
| 1003 | shape = XkbAddGeomShape(geom, nameAtom, shapeWire.num_outlines); | |||||
| 1004 | if (!shape) { | |||||
| 1005 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeometry", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeometry"); _XkbErrData = (0); }; | |||||
| 1006 | return nRead; | |||||
| 1007 | } | |||||
| 1008 | for (n = 0; n < shapeWire.num_outlines; n++) { | |||||
| 1009 | register int p; | |||||
| 1010 | xkmPointDesc ptWire; | |||||
| 1011 | ||||||
| 1012 | tmp = fread(&olWire, SIZEOF(xkmOutlineDesc)4, 1, file); | |||||
| 1013 | nRead += tmp * SIZEOF(xkmOutlineDesc)4; | |||||
| 1014 | ol = XkbAddGeomOutline(shape, olWire.num_points); | |||||
| 1015 | if (!ol) { | |||||
| 1016 | _XkbLibError(_XkbErrBadAlloc, "ReadXkmGeometry", 0){ _XkbErrCode= (23); _XkbErrLocation= ("ReadXkmGeometry"); _XkbErrData = (0); }; | |||||
| 1017 | return nRead; | |||||
| 1018 | } | |||||
| 1019 | ol->num_points = olWire.num_points; | |||||
| 1020 | ol->corner_radius = olWire.corner_radius; | |||||
| 1021 | for (p = 0; p < olWire.num_points; p++) { | |||||
| 1022 | tmp = fread(&ptWire, SIZEOF(xkmPointDesc)4, 1, file); | |||||
| 1023 | nRead += tmp * SIZEOF(xkmPointDesc)4; | |||||
| 1024 | ol->points[p].x = ptWire.x; | |||||
| 1025 | ol->points[p].y = ptWire.y; | |||||
| 1026 | if (ptWire.x < shape->bounds.x1) | |||||
| 1027 | shape->bounds.x1 = ptWire.x; | |||||
| 1028 | if (ptWire.x > shape->bounds.x2) | |||||
| 1029 | shape->bounds.x2 = ptWire.x; | |||||
| 1030 | if (ptWire.y < shape->bounds.y1) | |||||
| 1031 | shape->bounds.y1 = ptWire.y; | |||||
| 1032 | if (ptWire.y > shape->bounds.y2) | |||||
| 1033 | shape->bounds.y2 = ptWire.y; | |||||
| 1034 | } | |||||
| 1035 | } | |||||
| 1036 | if (shapeWire.primary_ndx != XkbNoShape0xff) | |||||
| 1037 | shape->primary = &shape->outlines[shapeWire.primary_ndx]; | |||||
| 1038 | if (shapeWire.approx_ndx != XkbNoShape0xff) | |||||
| 1039 | shape->approx = &shape->outlines[shapeWire.approx_ndx]; | |||||
| 1040 | } | |||||
| 1041 | } | |||||
| 1042 | if (wireGeom.num_sections > 0) { | |||||
| 1043 | for (i = 0; i < wireGeom.num_sections; i++) { | |||||
| 1044 | tmp = ReadXkmGeomSection(file, result->xkb->dpy, geom); | |||||
| 1045 | nRead += tmp; | |||||
| 1046 | if (tmp == 0) | |||||
| 1047 | return nRead; | |||||
| 1048 | } | |||||
| 1049 | } | |||||
| 1050 | if (wireGeom.num_doodads > 0) { | |||||
| 1051 | for (i = 0; i < wireGeom.num_doodads; i++) { | |||||
| 1052 | tmp = ReadXkmGeomDoodad(file, result->xkb->dpy, geom, NULL((void*)0)); | |||||
| 1053 | nRead += tmp; | |||||
| 1054 | if (tmp == 0) | |||||
| 1055 | return nRead; | |||||
| 1056 | } | |||||
| 1057 | } | |||||
| 1058 | if ((wireGeom.num_key_aliases > 0) && (geom->key_aliases)) { | |||||
| 1059 | int sz = XkbKeyNameLength4 * 2; | |||||
| 1060 | int num = wireGeom.num_key_aliases; | |||||
| 1061 | ||||||
| 1062 | if (fread(geom->key_aliases, sz, num, file) != num) { | |||||
| 1063 | _XkbLibError(_XkbErrBadLength, "ReadXkmGeometry", 0){ _XkbErrCode= (24); _XkbErrLocation= ("ReadXkmGeometry"); _XkbErrData = (0); }; | |||||
| 1064 | return -1; | |||||
| 1065 | } | |||||
| 1066 | nRead += (num * sz); | |||||
| 1067 | geom->num_key_aliases = num; | |||||
| 1068 | } | |||||
| 1069 | return nRead; | |||||
| 1070 | } | |||||
| 1071 | ||||||
| 1072 | Boolint | |||||
| 1073 | XkmProbe(FILE *file) | |||||
| 1074 | { | |||||
| 1075 | unsigned hdr, tmp; | |||||
| 1076 | int nRead = 0; | |||||
| 1077 | ||||||
| 1078 | hdr = (('x' << 24) | ('k' << 16) | ('m' << 8) | XkmFileVersion15); | |||||
| 1079 | tmp = XkmGetCARD32(file, &nRead); | |||||
| 1080 | if (tmp != hdr) { | |||||
| 1081 | if ((tmp & (~0xff)) == (hdr & (~0xff))) { | |||||
| 1082 | _XkbLibError(_XkbErrBadFileVersion, "XkmProbe", tmp & 0xff){ _XkbErrCode= (21); _XkbErrLocation= ("XkmProbe"); _XkbErrData = (tmp & 0xff); }; | |||||
| 1083 | } | |||||
| 1084 | return 0; | |||||
| 1085 | } | |||||
| 1086 | return 1; | |||||
| 1087 | } | |||||
| 1088 | ||||||
| 1089 | Boolint | |||||
| 1090 | XkmReadTOC(FILE *file, xkmFileInfo *file_info, | |||||
| 1091 | int max_toc, xkmSectionInfo *toc) | |||||
| 1092 | { | |||||
| 1093 | unsigned hdr, tmp; | |||||
| 1094 | int nRead = 0; | |||||
| 1095 | unsigned i, size_toc; | |||||
| 1096 | ||||||
| 1097 | hdr = (('x' << 24) | ('k' << 16) | ('m' << 8) | XkmFileVersion15); | |||||
| 1098 | tmp = XkmGetCARD32(file, &nRead); | |||||
| 1099 | if (tmp != hdr) { | |||||
| 1100 | if ((tmp & (~0xff)) == (hdr & (~0xff))) { | |||||
| 1101 | _XkbLibError(_XkbErrBadFileVersion, "XkmReadTOC", tmp & 0xff){ _XkbErrCode= (21); _XkbErrLocation= ("XkmReadTOC"); _XkbErrData = (tmp & 0xff); }; | |||||
| 1102 | } | |||||
| 1103 | else { | |||||
| 1104 | _XkbLibError(_XkbErrBadFileType, "XkmReadTOC", tmp){ _XkbErrCode= (20); _XkbErrLocation= ("XkmReadTOC"); _XkbErrData = (tmp); }; | |||||
| 1105 | } | |||||
| 1106 | return 0; | |||||
| 1107 | } | |||||
| 1108 | fread(file_info, SIZEOF(xkmFileInfo)8, 1, file); | |||||
| 1109 | size_toc = file_info->num_toc; | |||||
| 1110 | if (size_toc > max_toc) { | |||||
| 1111 | #ifdef DEBUG | |||||
| 1112 | fprintf(stderr__stderrp, "Warning! Too many TOC entries; last %d ignored\n", | |||||
| 1113 | size_toc - max_toc); | |||||
| 1114 | #endif | |||||
| 1115 | size_toc = max_toc; | |||||
| 1116 | } | |||||
| 1117 | for (i = 0; i < size_toc; i++) { | |||||
| 1118 | fread(&toc[i], SIZEOF(xkmSectionInfo)8, 1, file); | |||||
| 1119 | } | |||||
| 1120 | return 1; | |||||
| 1121 | } | |||||
| 1122 | ||||||
| 1123 | xkmSectionInfo * | |||||
| 1124 | XkmFindTOCEntry(xkmFileInfo *finfo, xkmSectionInfo *toc, unsigned type) | |||||
| 1125 | { | |||||
| 1126 | register int i; | |||||
| 1127 | ||||||
| 1128 | for (i = 0; i < finfo->num_toc; i++) { | |||||
| 1129 | if (toc[i].type == type) | |||||
| 1130 | return &toc[i]; | |||||
| 1131 | } | |||||
| 1132 | return NULL((void*)0); | |||||
| 1133 | } | |||||
| 1134 | ||||||
| 1135 | Boolint | |||||
| 1136 | XkmReadFileSection(FILE * file, | |||||
| 1137 | xkmSectionInfo * toc, | |||||
| 1138 | XkbFileInfo * result, | |||||
| 1139 | unsigned * loaded_rtrn) | |||||
| 1140 | { | |||||
| 1141 | xkmSectionInfo tmpTOC; | |||||
| 1142 | int nRead; | |||||
| 1143 | ||||||
| 1144 | if ((!result) || (!result->xkb)) { | |||||
| 1145 | _XkbLibError(_XkbErrBadMatch, "XkmReadFileSection", 0){ _XkbErrCode= (17); _XkbErrLocation= ("XkmReadFileSection"); _XkbErrData= (0); }; | |||||
| 1146 | return 0; | |||||
| 1147 | } | |||||
| 1148 | fseek(file, toc->offset, SEEK_SET0); | |||||
| 1149 | fread(&tmpTOC, SIZEOF(xkmSectionInfo)8, 1, file); | |||||
| 1150 | nRead = SIZEOF(xkmSectionInfo)8; | |||||
| 1151 | if ((tmpTOC.type != toc->type) || (tmpTOC.format != toc->format) || | |||||
| 1152 | (tmpTOC.size != toc->size) || (tmpTOC.offset != toc->offset)) { | |||||
| 1153 | _XkbLibError(_XkbErrIllegalContents, "XkmReadFileSection", 0){ _XkbErrCode= (12); _XkbErrLocation= ("XkmReadFileSection"); _XkbErrData= (0); }; | |||||
| 1154 | return 0; | |||||
| 1155 | } | |||||
| 1156 | switch (tmpTOC.type) { | |||||
| 1157 | case XkmVirtualModsIndex6: | |||||
| 1158 | nRead += ReadXkmVirtualMods(file, result, NULL((void*)0)); | |||||
| 1159 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1160 | *loaded_rtrn |= XkmVirtualModsMask(1<<6); | |||||
| 1161 | break; | |||||
| 1162 | case XkmTypesIndex0: | |||||
| 1163 | nRead += ReadXkmKeyTypes(file, result, NULL((void*)0)); | |||||
| 1164 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1165 | *loaded_rtrn |= XkmTypesMask(1<<0); | |||||
| 1166 | break; | |||||
| 1167 | case XkmCompatMapIndex1: | |||||
| 1168 | nRead += ReadXkmCompatMap(file, result, NULL((void*)0)); | |||||
| 1169 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1170 | *loaded_rtrn |= XkmCompatMapMask(1<<1); | |||||
| 1171 | break; | |||||
| 1172 | case XkmKeyNamesIndex4: | |||||
| 1173 | nRead += ReadXkmKeycodes(file, result, NULL((void*)0)); | |||||
| 1174 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1175 | *loaded_rtrn |= XkmKeyNamesMask(1<<4); | |||||
| 1176 | break; | |||||
| 1177 | case XkmSymbolsIndex2: | |||||
| 1178 | nRead += ReadXkmSymbols(file, result); | |||||
| 1179 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1180 | *loaded_rtrn |= XkmSymbolsMask(1<<2); | |||||
| 1181 | break; | |||||
| 1182 | case XkmIndicatorsIndex3: | |||||
| 1183 | nRead += ReadXkmIndicators(file, result, NULL((void*)0)); | |||||
| 1184 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1185 | *loaded_rtrn |= XkmIndicatorsMask(1<<3); | |||||
| 1186 | break; | |||||
| 1187 | case XkmGeometryIndex5: | |||||
| 1188 | nRead += ReadXkmGeometry(file, result); | |||||
| 1189 | if ((loaded_rtrn) && (nRead >= 0)) | |||||
| 1190 | *loaded_rtrn |= XkmGeometryMask(1<<5); | |||||
| 1191 | break; | |||||
| 1192 | default: | |||||
| 1193 | _XkbLibError(_XkbErrBadImplementation,{ _XkbErrCode= (26); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (0); } | |||||
| 1194 | XkbConfigText(tmpTOC.type, XkbMessage), 0){ _XkbErrCode= (26); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (0); }; | |||||
| 1195 | nRead = 0; | |||||
| 1196 | break; | |||||
| 1197 | } | |||||
| 1198 | if (nRead != tmpTOC.size) { | |||||
| 1199 | _XkbLibError(_XkbErrBadLength, XkbConfigText(tmpTOC.type, XkbMessage),{ _XkbErrCode= (24); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (nRead - tmpTOC.size); } | |||||
| 1200 | nRead - tmpTOC.size){ _XkbErrCode= (24); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (nRead - tmpTOC.size); }; | |||||
| 1201 | return 0; | |||||
| 1202 | } | |||||
| 1203 | return (nRead >= 0); | |||||
| 1204 | } | |||||
| 1205 | ||||||
| 1206 | char * | |||||
| 1207 | XkmReadFileSectionName(FILE *file, xkmSectionInfo *toc) | |||||
| 1208 | { | |||||
| 1209 | xkmSectionInfo tmpTOC; | |||||
| 1210 | char name[100]; | |||||
| 1211 | ||||||
| 1212 | if ((!file) || (!toc)) | |||||
| ||||||
| 1213 | return NULL((void*)0); | |||||
| 1214 | switch (toc->type) { | |||||
| 1215 | case XkmVirtualModsIndex6: | |||||
| 1216 | case XkmIndicatorsIndex3: | |||||
| 1217 | break; | |||||
| 1218 | case XkmTypesIndex0: | |||||
| 1219 | case XkmCompatMapIndex1: | |||||
| 1220 | case XkmKeyNamesIndex4: | |||||
| 1221 | case XkmSymbolsIndex2: | |||||
| 1222 | case XkmGeometryIndex5: | |||||
| 1223 | fseek(file, toc->offset, SEEK_SET0); | |||||
| 1224 | fread(&tmpTOC, SIZEOF(xkmSectionInfo)8, 1, file); | |||||
| 1225 | if ((tmpTOC.type != toc->type) || (tmpTOC.format != toc->format) || | |||||
| 1226 | (tmpTOC.size != toc->size) || (tmpTOC.offset != toc->offset)) { | |||||
| 1227 | _XkbLibError(_XkbErrIllegalContents, "XkmReadFileSectionName", 0){ _XkbErrCode= (12); _XkbErrLocation= ("XkmReadFileSectionName" ); _XkbErrData= (0); }; | |||||
| 1228 | return NULL((void*)0); | |||||
| 1229 | } | |||||
| 1230 | if (XkmGetCountedString(file, name, 100) > 0) | |||||
| 1231 | return _XkbDupString(name); | |||||
| 1232 | break; | |||||
| 1233 | default: | |||||
| 1234 | _XkbLibError(_XkbErrBadImplementation,{ _XkbErrCode= (26); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (0); } | |||||
| ||||||
| 1235 | XkbConfigText(tmpTOC.type, XkbMessage), 0){ _XkbErrCode= (26); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (0); }; | |||||
| 1236 | break; | |||||
| 1237 | } | |||||
| 1238 | return NULL((void*)0); | |||||
| 1239 | } | |||||
| 1240 | ||||||
| 1241 | /***====================================================================***/ | |||||
| 1242 | ||||||
| 1243 | #define MAX_TOC16 16 | |||||
| 1244 | unsigned | |||||
| 1245 | XkmReadFile(FILE *file, unsigned need, unsigned want, XkbFileInfo *result) | |||||
| 1246 | { | |||||
| 1247 | register unsigned i; | |||||
| 1248 | xkmSectionInfo toc[MAX_TOC16], tmpTOC; | |||||
| 1249 | xkmFileInfo fileInfo; | |||||
| 1250 | unsigned tmp, nRead = 0; | |||||
| 1251 | unsigned which = need | want; | |||||
| 1252 | ||||||
| 1253 | if (!XkmReadTOC(file, &fileInfo, MAX_TOC16, toc)) | |||||
| 1254 | return which; | |||||
| 1255 | if ((fileInfo.present & need) != need) { | |||||
| 1256 | _XkbLibError(_XkbErrIllegalContents, "XkmReadFile",{ _XkbErrCode= (12); _XkbErrLocation= ("XkmReadFile"); _XkbErrData = (need & (~fileInfo.present)); } | |||||
| 1257 | need & (~fileInfo.present)){ _XkbErrCode= (12); _XkbErrLocation= ("XkmReadFile"); _XkbErrData = (need & (~fileInfo.present)); }; | |||||
| 1258 | return which; | |||||
| 1259 | } | |||||
| 1260 | result->type = fileInfo.type; | |||||
| 1261 | if (result->xkb == NULL((void*)0)) | |||||
| 1262 | result->xkb = XkbAllocKeyboard(); | |||||
| 1263 | for (i = 0; i < fileInfo.num_toc; i++) { | |||||
| 1264 | fseek(file, toc[i].offset, SEEK_SET0); | |||||
| 1265 | tmp = fread(&tmpTOC, SIZEOF(xkmSectionInfo)8, 1, file); | |||||
| 1266 | nRead = tmp * SIZEOF(xkmSectionInfo)8; | |||||
| 1267 | if ((tmpTOC.type != toc[i].type) || (tmpTOC.format != toc[i].format) || | |||||
| 1268 | (tmpTOC.size != toc[i].size) || (tmpTOC.offset != toc[i].offset)) { | |||||
| 1269 | return which; | |||||
| 1270 | } | |||||
| 1271 | if ((which & (1 << tmpTOC.type)) == 0) { | |||||
| 1272 | continue; | |||||
| 1273 | } | |||||
| 1274 | switch (tmpTOC.type) { | |||||
| 1275 | case XkmVirtualModsIndex6: | |||||
| 1276 | tmp = ReadXkmVirtualMods(file, result, NULL((void*)0)); | |||||
| 1277 | break; | |||||
| 1278 | case XkmTypesIndex0: | |||||
| 1279 | tmp = ReadXkmKeyTypes(file, result, NULL((void*)0)); | |||||
| 1280 | break; | |||||
| 1281 | case XkmCompatMapIndex1: | |||||
| 1282 | tmp = ReadXkmCompatMap(file, result, NULL((void*)0)); | |||||
| 1283 | break; | |||||
| 1284 | case XkmKeyNamesIndex4: | |||||
| 1285 | tmp = ReadXkmKeycodes(file, result, NULL((void*)0)); | |||||
| 1286 | break; | |||||
| 1287 | case XkmIndicatorsIndex3: | |||||
| 1288 | tmp = ReadXkmIndicators(file, result, NULL((void*)0)); | |||||
| 1289 | break; | |||||
| 1290 | case XkmSymbolsIndex2: | |||||
| 1291 | tmp = ReadXkmSymbols(file, result); | |||||
| 1292 | break; | |||||
| 1293 | case XkmGeometryIndex5: | |||||
| 1294 | tmp = ReadXkmGeometry(file, result); | |||||
| 1295 | break; | |||||
| 1296 | default: | |||||
| 1297 | _XkbLibError(_XkbErrBadImplementation,{ _XkbErrCode= (26); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (0); } | |||||
| 1298 | XkbConfigText(tmpTOC.type, XkbMessage), 0){ _XkbErrCode= (26); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (0); }; | |||||
| 1299 | tmp = 0; | |||||
| 1300 | break; | |||||
| 1301 | } | |||||
| 1302 | if (tmp > 0) { | |||||
| 1303 | nRead += tmp; | |||||
| 1304 | which &= ~(1 << toc[i].type); | |||||
| 1305 | result->defined |= (1 << toc[i].type); | |||||
| 1306 | } | |||||
| 1307 | if (nRead != tmpTOC.size) { | |||||
| 1308 | _XkbLibError(_XkbErrBadLength,{ _XkbErrCode= (24); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (nRead - tmpTOC.size); } | |||||
| 1309 | XkbConfigText(tmpTOC.type, XkbMessage),{ _XkbErrCode= (24); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (nRead - tmpTOC.size); } | |||||
| 1310 | nRead - tmpTOC.size){ _XkbErrCode= (24); _XkbErrLocation= (XkbConfigText(tmpTOC.type , 3)); _XkbErrData= (nRead - tmpTOC.size); }; | |||||
| 1311 | } | |||||
| 1312 | } | |||||
| 1313 | return which; | |||||
| 1314 | } |