/* Copyright 1998 Acorn Computers Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include "Unicode/iso10646.h" #include "unicdata.h" #include "structures.h" #include "throwback.h" #define MAX_FILE_DEPTH 16 FILE *sourcefile[MAX_FILE_DEPTH]; char *sourcefilename[MAX_FILE_DEPTH]; int sourceline[MAX_FILE_DEPTH]; int filedepth; const char *ExtraKeys, *FNKey; char keypad_codes[]={ 0x23, 0x24, 0x25, 0x37, 0x38, 0x39, 0x3A, 0x48, 0x49, 0x4A, 0x4B, 0x5A, 0x5B, 0x5C, 0x65, 0x66, 0x67, 0 }; typedef struct charinfo { UCS4 code; char *name; } charinfo; /* Must be sorted */ charinfo funclist[] = { 0xC0, "ACORN", 0xC8, "ALL CANDIDATES", 0x08, "BACKSPACE", 0x8A, "BREAK", 0xC6, "CONVERT", 0x8B, "COPY", 0x7F, "DELETE", 0x8E, "DOWN", 0xC4, "EISUU", 0x8B, "END", 0x0D, "ENTER", 0x1B, "ESCAPE", 0x81, "F1", 0xCA, "F10", 0xCB, "F11", 0xCC, "F12", 0x82, "F2", 0x83, "F3", 0x84, "F4", 0x85, "F5", 0x86, "F6", 0x87, "F7", 0x88, "F8", 0x89, "F9", 0x1E, "HOME", 0xCD, "INSERT", 0xC7, "KANA", 0xC3, "KANJI", 0xC9, "KANJI NUMBER", 0x8C, "LEFT", 0xC1, "MENU", 0xC5, "NO CONVERSION", 0x9E, "PAGE DOWN", 0x9F, "PAGE UP", 0x80, "PRINT", 0x8D, "RIGHT", 0x8F, "UP", 0xC2, "WIDTH", }; #define FUNCTIONS (sizeof funclist / sizeof funclist[0]) charinfo speclist[] = { 0x03, "CAPS LOCK", 0x07, "CONFIGURED KEYBOARD", 0x06, "DEFAULT KEYBOARD", 0x09, "DELETE", 0x08, "DIAL KEYBOARD", 0x04, "KANA LOCK", 0x01, "NUM LOCK", 0x00, "SCROLL LOCK", 0x05, "SHIFT-CAPS LOCK", 0x02, "TAB", }; #define SPECIALS (sizeof speclist / sizeof speclist[0]) charinfo deadlist[] = { 2, "ACUTE ACCENT", 6, "BREVE", 11, "CARON", 13, "CEDILLA", 3, "CIRCUMFLEX ACCENT", 8, "DIAERESIS", 7, "DOT ABOVE", 10, "DOUBLE ACUTE ACCENT", 1, "GRAVE ACCENT", 8, "GREEK DIALYTIKA", 15, "GREEK DIALYTIKA TONOS", 12, "GREEK TONOS", 5, "MACRON", 14, "OGONEK", 9, "RING ABOVE", 16, "STROKE", 4, "TILDE", 12, "VERTICAL LINE ABOVE", }; #define DEADS (sizeof deadlist / sizeof deadlist[0]) const char *current_output_file; FILE *current_output_handle; static int throwback, depend; void error(const char *p) { fprintf(stderr, "%s, line %d: %s\n", sourcefilename[filedepth], sourceline[filedepth], p); if (throwback) throwback_send(1, sourceline[filedepth], p, sourcefilename[0], sourcefilename[filedepth]); fclose(current_output_handle); remove(current_output_file); exit(1); } static int cmp_name2(const void *p1, const void *p2) { char *n = (char *) p1; charinfo *c2 = (charinfo *) p2; return strcmp(n, c2->name); } static UCS4 function_key_code(const char *p) { UCS4 c, c2; int ctrl=0, shift=0; charinfo *ci; /* Check for raw &8A */ if (*p == '&' && *(p+1) != '\0') { char *end; c = (UCS4) strtol(p+1, &end, 16); if (*end != '\0' || c < 0x80 || c >= 0xFF) error("Bad hex"); return 0x80000000 + c; } /* Check for CTRL-B etc */ if (strncmp(p, "CTRL-", 5) == 0) { c = p[5]; c2 = p[6]; if (c >= '@' && c <= '_' && c2 == '\0') return c-'@'; if (c == '?' && c2 == '\0') return 127; } /* CTRL and SHIFT modifiers for other keys */ if (strncmp(p, "CTRL-", 5) == 0) { ctrl = 0x20; p+=5; } if (strncmp(p, "SHIFT-", 6) == 0) { shift = 0x10; p+=6; } ci = (charinfo *) bsearch(p, funclist, FUNCTIONS, sizeof funclist[0], cmp_name2); if (ci == NULL) { error("Unknown function key"); return NULL_UCS4; } if (ci->code < 0x80) { /* no shift/ctrl variants of these codes, and bit 31 needn't be set */ return ci->code; } return (0x80000000 + ci->code) ^ ctrl ^ shift; } static UCS4 special_key_code(const char *p) { charinfo *ci; ci = (charinfo *) bsearch(p, speclist, SPECIALS, sizeof speclist[0], cmp_name2); if (ci == NULL) { error("Unknown special key"); return NULL_UCS4; } return 0x80010000 + ci->code; } static UCS4 dead_key_code(const char *p) { charinfo *ci; ci = (charinfo *) bsearch(p, deadlist, DEADS, sizeof deadlist[0], cmp_name2); if (ci == NULL) { error("Unknown dead key"); return NULL_UCS4; } return 0x80020000 + ci->code; } UCS4 keycode_from_name(const char *name) { if (name[0]=='-' && name[1]=='\0') return NULL_UCS4; if (strncmp(name, "FUNCTION KEY ", 13)==0) return function_key_code(name+13); if (strncmp(name, "SPECIAL KEY ", 12)==0) return special_key_code(name+12); if (strncmp(name, "DEAD KEY ", 9)==0) return dead_key_code(name+9); return UCS_from_name(name); } char *getline(char *p, size_t plen) { char *ret; int l; start_again: do { sourceline[filedepth]++; ret = fgets(p, plen, sourcefile[filedepth]); if (!ret) { /* EOF - either return from the current include file, or give up */ if (filedepth) { free(sourcefilename[filedepth]); fclose(sourcefile[filedepth]); sourcefile[filedepth--] = NULL; l = 0; continue; } else return NULL; } l = strlen(p); if (p[l-1] == '\n') p[--l] = '\0'; while (l && p[l-1] == ' ') p[--l] = '\0'; } while (l == 0 || p[0] == '#'); if (p[0] == '%' && memcmp(p, "%Include ", 9) == 0) { if (filedepth == MAX_FILE_DEPTH-1) error("%Include depth too great"); else { const char *newinclude; if (strcmp(p+9, "@ExtraKeys@") == 0) { if (ExtraKeys) newinclude = ExtraKeys; else goto start_again; } else if (strcmp(p+9, "@FNKey@") == 0) { if (FNKey) newinclude = FNKey; else goto start_again; } else newinclude = p+9; /* Mustn't increment filedepth until all errors cleared */ if ((sourcefile[filedepth+1] = fopen(newinclude, "r")) == NULL) error("Unable to open %Include file"); if ((sourcefilename[filedepth+1]=malloc(strlen(newinclude)+1)) == NULL) error("Out of memory"); strcpy(sourcefilename[++filedepth], newinclude); sourceline[filedepth]=0; if (depend) add_dependency(current_output_file, sourcefilename[filedepth]); goto start_again; } } return p; } #define K_ScrollLock 0x0E #define K_Break 0x0F #define K_NumLock 0x22 #define K_NumPadSlash 0x23 #define K_NumPadStar 0x24 #define K_NumPadHash 0x25 #define K_Tab 0x26 #define K_NumPad7 0x37 #define K_NumPad8 0x38 #define K_NumPad9 0x39 #define K_NumPadMinus 0x3A #define K_CtrlL 0x3B #define K_NumPad4 0x48 #define K_NumPad5 0x49 #define K_NumPad6 0x4A #define K_NumPadPlus 0x4B #define K_ShiftL 0x4C #define K_ShiftR 0x58 #define K_NumPad1 0x5A #define K_NumPad2 0x5B #define K_NumPad3 0x5C #define K_CapsLock 0x5D #define K_AltL 0x5E #define K_AltR 0x60 #define K_CtrlR 0x61 #define K_NumPad0 0x65 #define K_NumPadDot 0x66 #define K_NumPadEnter 0x67 #define K_FN 0x6F #define K_MSelect 0x70 #define K_MMenu 0x71 #define K_MAdjust 0x72 int is_modifier_key(int key) { return key == K_Break || key == K_CtrlL || key == K_ShiftL || key == K_ShiftR || key == K_AltL || key == K_AltR || key == K_CtrlR || key == K_FN || key == K_MSelect || key == K_MMenu || key == K_MAdjust; } int is_keypad_key(int key) { return key != 0 && strchr(keypad_codes, key) != NULL; } int is_special_key(int key) { return key == K_ScrollLock || key == K_NumLock || key == K_Tab || key == K_CapsLock || is_modifier_key(key); } void read_keypad(Keyboard *kb) { int i=0; char buffer[256]; char *second, *p; UCS4 k, k2; while (getline(buffer, 256)) { if (buffer[0] == '$') { if (strcmp(buffer, "$EndKeypad")==0) { if (i < 17) error("Too few keypad keys"); return; } else error("Unexpected directive"); } if (i >= 17) error("Too many keypad keys"); second = strchr(buffer, ';'); if (second) { *second='\0'; p = (second++)-1; while (p>=buffer && *p==' ') *p--='\0'; while (*second==' ') second++; } k = keycode_from_name(buffer); if (second) k2 = keycode_from_name(second); else k2 = k; if ((k >= 0x80 && k < 0x80000080) || (k >= 0x800000FF && k < 0xFFFFFFFF) || (k2 >= 0x80 && k2 < 0x80000080) || (k2 >= 0x800000FF && k2 < 0xFFFFFFFF)) error("I'm afraid you can't put that character on the keypad"); kb->keypad[0][i]=(char)k; kb->keypad[1][i++]=(char)k2; } error("Unexpected end of file"); } void read_fnkey(Keyboard *kb) { int i=0; char buffer[256]; char *p; unsigned long k, k2; for (i=0; ikey[i].fn = -1; kb->fnused = false; i = 0; while (getline(buffer, 256)) { if (buffer[0] == '$') { if (strcmp(buffer, "$EndFNKey")==0) { return; } else error("Unexpected directive"); } k = strtoul(buffer, &p, 16); if (k >= MAXKEYS) error("Expected key number"); k2 = strtoul(p, NULL, 16); if (k2 >= MAXKEYS || k == k2) error("Expected key number"); /* Can only map non-modifier keys to other non-modifier keys */ if (is_modifier_key((int) k) && !kb->key[k].defined || is_modifier_key((int) k2) && !kb->key[k2].defined) error("I'm sorry, I'm afraid I can't do that"); kb->key[k].defined = 1; kb->key[k2].defined = 1; kb->key[k].fn = (int) k2; kb->fnused = true; if (++i > 0xFF) error("Too many FN mappings"); } error("Unexpected end of file"); } void read_layer(Keyboard *kb, int layerno) { char buffer[256]; char scaps[8], caps[8]; int key, i, replace=0; char *p; while (getline(buffer, 256)) { char uc[4]; if (buffer[0] == '$') { if (strcmp(buffer, "$EndLayer")==0) return; } key = (int) strtol(buffer, &p, 16); if (p == buffer || key < 0 || key >= MAXKEYS) error("Expected key number"); while (*p <= ' ' && *p != '\0') p++; if (*p != '\0') { if (strcmp(p, "replace") == 0) replace = 1; else error("Unexpected trailing garbage after key number"); } if (!replace && kb->key[key].definedinlayer[layerno]) error("Key already defined"); if (is_modifier_key(key)) kb->needshiftinglist = 1; if (is_keypad_key(key)) error("Use $Keypad to alter keypad keys"); if (is_special_key(key)) kb->needcodetable = 1; kb->key[key].defined = 1; kb->key[key].definedinlayer[layerno] = 1; if (key >= kb->numkeys) { kb->numkeys = key + 1; } for (i=0; i<8; i++) { char *p=buffer, *q; static const char brack[] = "-[]-{}-()-<>"; if (getline(buffer, 256) == NULL) error("Error reading key"); q = *p != '-' ? strchr(brack, *p) : NULL; if (q) { uc[i] = q-brack+1; p++; } else uc[i] = 0; kb->key[key].character[layerno][i] = keycode_from_name(p); } /* Now we need to figure out the Caps Lock and Shift-Caps lock mappings. * The logic here is that two parts of a key may be an upper/lower pair, * marked with [ ] or { }. When Caps Lock is in force, you should always * get the upper case form of anything you press. When Shift-Caps is in * force, you should get the opposite case of anything you press. */ kb->key[key].caps[layerno] = 0; for (i=0; i<8; i++) { int j; caps[i]=scaps[i]=i; for (j=0; j<8; j++) { if (uc[j] == uc[i] + 1) { caps[i] = j; scaps[i] = j; } else if (uc[j] == uc[i] - 1) scaps[i] = j; } if (caps[i] == scaps[i]) { kb->key[key].caps[layerno] |= caps[i] << i*4; } else { if (caps[i] == i) kb->key[key].caps[layerno] |= (scaps[i]|8) << i*4; else error("Inconsistent Caps Lock pairs"); } } /* Now we work out if this is an "easy" key, ie one that the * kernel can handle itself. */ kb->key[key].easylayer[layerno] = 0; for (i=0; i<8; i++) { UCS4 c = kb->key[key].character[layerno][i]; kb->key[key].easych[layerno][i]=0; if ((i < 4 && (c <= 0x7F || c >= 0x80000080 && c <= 0x800000FE)) || c == 0xFFFFFFFF) { UCS4 kc, ksc; /* Okay, it's one of the kernel's 00-FF codes. What will the kernel * do with Caps-Lock? */ if ((c &~ 0x20) >= 'A' && (c &~ 0x20) <= 'Z') { ksc = c ^ 0x20; kc = c &~ 0x20; } else kc = ksc = c; /* Does it match what we want? */ if (ksc == kb->key[key].character[layerno][scaps[i]] && kc == kb->key[key].character[layerno][caps[i]]) { kb->key[key].easylayer[layerno]++; kb->key[key].easych[layerno][i]=1; } } } if (kb->key[key].easylayer[layerno] < 8) kb->key[key].easylayer[layerno] = 0; } error("Unexpected end of file"); } void *xmalloc(size_t s) { void *ret = malloc(s); if (!ret) error("Out of memory"); return ret; } void read_layout_file(Keyboard *kb) { char buffer[256]; int layer = -1; while (getline(buffer, 256)) { if (buffer[0] == '$') { if (memcmp(buffer, "$Country ", 9)==0) kb->country = atoi(buffer + 9); else if (strcmp(buffer, "$LeftAltLayerSwitch")==0) { kb->leftaltlayerswitch = 1; kb->needcodetable = 1; } else if (memcmp(buffer, "$Layer ", 7)==0) { layer = atoi(buffer + 7); if (layer < 0 || layer >= MAXLAYERS) error("Bad layer number"); if (layer < kb->layers) error("Layer already defined"); read_layer(kb, layer); kb->layers++; } else if (strcmp(buffer, "$Keypad")==0) { if (kb->custompad) error("Keypad already defined"); kb->custompad=1; read_keypad(kb); } else if (strcmp(buffer, "$FNKey")==0) read_fnkey(kb); else error("Unknown directive"); } else error("Expecting a $ directive"); } } void output_layer(FILE *out, Keyboard *kb, int layerno) { int i; fprintf(out, "\nUCSTable%d_%d\n", kb->country, layerno); for (i=0; i < MAXKEYS; i++) { if (kb->key[i].defined && !kb->key[i].easy) fprintf(out, " & &%08X,&%08X,&%08X,&%08X ; &%02X\n" " & &%08X,&%08X,&%08X,&%08X, &%08X\n", kb->key[i].character[layerno][0], kb->key[i].character[layerno][1], kb->key[i].character[layerno][2], kb->key[i].character[layerno][3], i, kb->key[i].character[layerno][4], kb->key[i].character[layerno][5], kb->key[i].character[layerno][6], kb->key[i].character[layerno][7], kb->key[i].caps[layerno]); } } void output_simples(FILE *out, Keyboard *kb) { int i,j,c, best; int t; if (kb->fnused) { /* Sorry lads, if FN's in use we can't have any simple keys */ for (i=0; ikey[i].easy = 0; best = 0; } else { int bestmem; int specials; for (i=0; ikey[i].easy = 1; for (j=0; jlayers; j++) { if (!kb->key[i].easylayer[j]) { kb->key[i].easy = 0; break; } for (c=0; c<8; c++) if (kb->key[i].character[j][c] != kb->key[i].character[0][c]) { kb->key[i].easy = 0; break; } } } /* How many should we put in the "easy" array? Want to * minimise memory usage. The memory usage is basically * 4 * (highest easy key+1) for the KeyTran table * + 36 * special keys * layers + special keys. for SpecialList + UCSList * * Start off supposing every defined key is special, * then try effect of gradually extending the simple table. */ for (i=0, specials=0; i < MAXKEYS; i++) if (kb->key[i].defined) specials++; bestmem = 36*specials*kb->layers + specials; best = 0; for (i=0; i < MAXKEYS; i++) { int mem; if (kb->key[i].easy && kb->key[i].defined) // we've saved one special code!! specials--; mem = (i+1)*4 + 36*specials*kb->layers + specials; /*printf("%d simple, %d special, mem = %d\n", i, specials, mem);*/ if (memkey[i].easy=0; } fprintf(out, "KeyTran%d\n", kb->country); for (i=0; i < best; i++) if (kb->key[i].easy) fprintf(out, " = &%02X, &%02X, &%02X, &%02X\n", kb->key[i].easych[0][0] ? kb->key[i].character[0][0]&0xFF : 0xFF, kb->key[i].easych[0][1] ? kb->key[i].character[0][1]&0xFF : 0xFF, kb->key[i].easych[0][2] ? kb->key[i].character[0][2]&0xFF : 0xFF, kb->key[i].easych[0][3] ? kb->key[i].character[0][3]&0xFF : 0xFF); else fprintf(out, " = &FF, &FF, &FF, &FF\n"); fprintf(out, "KeyTran%dEnd\n\n", kb->country); fprintf(out, "\nSpecialList%d\n" " = SpecialList%dEnd - SpecialList%d - 1\n", kb->country, kb->country, kb->country); t=1; if (!kb->key[K_ShiftL].defined) { fprintf(out, " = K1ShiftLeft\n"); t++; } if (!kb->key[K_ShiftR].defined) { fprintf(out, " = K1ShiftRight\n"); t++; } if (!kb->key[K_CtrlL].defined) { fprintf(out, " = K1CtrlLeft\n"); t++; } if (!kb->key[K_CtrlR].defined) { fprintf(out, " = K1CtrlRight\n"); t++; } if (!kb->key[K_AltL].defined) { fprintf(out, " = K1AltLeft\n"); t++; } if (!kb->key[K_AltR].defined) { fprintf(out, " = K1AltRight\n"); t++; } if (!kb->key[K_FN].defined) { fprintf(out, " = K1FN\n"); t++; } if (!kb->key[K_MSelect].defined) { fprintf(out, " = K1LeftMouse\n"); t++; } if (!kb->key[K_MMenu].defined) { fprintf(out, " = K1CentreMouse\n"); t++; } if (!kb->key[K_MAdjust].defined) { fprintf(out, " = K1RightMouse\n"); t++; } if (!kb->key[K_Break].defined) { fprintf(out, " = K1Break\n"); kb->key[K_Break].tablenum=t++; } fprintf(out, "SpecialList%dPad\n" " = K1NumPadSlash, K1NumPadStar, K1NumPadHash\n" " = K1NumPad7, K1NumPad8, K1NumPad9, K1NumPadMinus\n" " = K1NumPad4, K1NumPad5, K1NumPad6, K1NumPadPlus\n" " = K1NumPad1, K1NumPad2, K1NumPad3\n" " = K1NumPad0, K1NumPadDot, K1NumPadEnter\n", kb->country); kb->key[K_NumPadSlash].tablenum=t++; kb->key[K_NumPadStar].tablenum=t++; kb->key[K_NumPadHash].tablenum=t++; kb->key[K_NumPad7].tablenum=t++; kb->key[K_NumPad8].tablenum=t++; kb->key[K_NumPad9].tablenum=t++; kb->key[K_NumPadMinus].tablenum=t++; kb->key[K_NumPad4].tablenum=t++; kb->key[K_NumPad5].tablenum=t++; kb->key[K_NumPad6].tablenum=t++; kb->key[K_NumPadPlus].tablenum=t++; kb->key[K_NumPad1].tablenum=t++; kb->key[K_NumPad2].tablenum=t++; kb->key[K_NumPad3].tablenum=t++; kb->key[K_NumPad0].tablenum=t++; kb->key[K_NumPadDot].tablenum=t++; kb->key[K_NumPadEnter].tablenum=t++; if (!kb->key[K_ScrollLock].defined) { fprintf(out, " = K1ScrollLock\n"); kb->key[K_ScrollLock].tablenum=t++; } if (!kb->key[K_NumLock].defined) { fprintf(out, " = K1NumLock\n"); kb->key[K_NumLock].tablenum=t++; } if (!kb->key[K_Tab].defined) { fprintf(out, " = K1Tab\n"); kb->key[K_Tab].tablenum=t++; } if (!kb->key[K_CapsLock].defined) { fprintf(out, " = K1CapsLock\n"); kb->key[K_CapsLock].tablenum=t++; } fprintf(out, "SpecialList%dUCS", kb->country); for (j=0, i=0; ikey[i].defined && !kb->key[i].easy) { fprintf(out, "%s&%02X", j==0 ? "\n = " : ", ", i); j = (j+1)%8; kb->key[i].tablenum = t++; } fprintf(out, "\nSpecialList%dEnd\n" " ALIGN\n", kb->country); } void process_keyboard(FILE *in, FILE *out) { int i, k, c; Keyboard *kb = xmalloc(sizeof *kb); kb->country = -1; kb->layers = 0; kb->numkeys = 0; kb->fnused = false; kb->needcodetable = 0; kb->needshiftinglist = 0; kb->custompad = 0; kb->leftaltlayerswitch = 0; sourcefile[0] = in; for (k=0; kkey[k].defined = 0; kb->key[k].tablenum = 0; kb->key[k].easy = 1; for (i=0; ikey[k].character[i][c] = NULL_UCS4; kb->key[k].easych[i][c]=1; } kb->key[k].caps[i]=(0<<0)|(1<<4)|(2<<8)|(3<<12)|(4<<16)|(5<<20)|(6<<24)|(7<<28); kb->key[k].definedinlayer[i]=0; kb->key[k].easylayer[i]=1; } } read_layout_file(kb); fprintf(out, "KeyStruct%d\n" " & KeyTran%d-KeyStruct%d\n" " & (KeyTran%dEnd-KeyTran%d) :SHR: 2\n" " & InkeyTran-KeyStruct%d\n", kb->country, kb->country, kb->country, kb->country, kb->country, kb->country); if (kb->needshiftinglist) fprintf(out, " & ShiftingKeyList%d-KeyStruct%d\n", kb->country, kb->country); else fprintf(out, " & ShiftingKeyList-KeyStruct%d\n", kb->country); fprintf(out, " & SpecialList%d-KeyStruct%d\n", kb->country, kb->country); if (kb->needcodetable) fprintf(out, " & SpecialCodeTable%d-KeyStruct%d\n", kb->country, kb->country); else fprintf(out, " & SpecialCodeTable-KeyStruct%d\n", kb->country); fprintf(out, " & KeyStructInit-KeyStruct%d\n" " & PendingAltCode-KeyStruct%d\n", kb->country, kb->country); if (kb->custompad) fprintf(out, " & PadK%dNumTran-KeyStruct%d-(SpecialList%dPad-SpecialList%d)\n" " & PadK%dCurTran-KeyStruct%d-(SpecialList%dPad-SpecialList%d)\n", kb->country, kb->country, kb->country, kb->country, kb->country, kb->country, kb->country, kb->country); else fprintf(out, " & PadKNumTran-KeyStruct%d-(SpecialList%dPad-SpecialList%d)\n" " & PadKCurTran-KeyStruct%d-(SpecialList%dPad-SpecialList%d)\n", kb->country, kb->country, kb->country, kb->country, kb->country, kb->country); if (kb->fnused) fprintf(out, " & FNTable%d-KeyStruct%d\n", kb->country, kb->country); else fprintf(out, " & 0\n"); for (i=0; i < MAXLAYERS; i++) { int j = i < kb->layers ? i : 0; fprintf(out, " & UCSTable%d_%d-KeyStruct%d-(SpecialList%dUCS-SpecialList%d)*36\n", kb->country, j, kb->country, kb->country, kb->country); } fprintf(out, "\n"); output_simples(out, kb); if (kb->needcodetable) { fprintf(out, "\nSpecialCodeTable%d\n", kb->country); if (!kb->key[K_ShiftL].defined) fprintf(out, " & ProcessKShift - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_ShiftR].defined) fprintf(out, " & ProcessKShift - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_CtrlL].defined) fprintf(out, " & ProcessKCtrl - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_CtrlR].defined) fprintf(out, " & ProcessKCtrl - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_AltL].defined) { if (kb->leftaltlayerswitch) fprintf(out, " & ProcessKAltLeft - SpecialCodeTable%d\n", kb->country); else fprintf(out, " & ProcessKAlt - SpecialCodeTable%d\n", kb->country); } if (!kb->key[K_AltR].defined) fprintf(out, " & ProcessKAlt - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_FN].defined) fprintf(out, " & ProcessKFN - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_MSelect].defined) fprintf(out, " & ProcessKLeft - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_MMenu].defined) fprintf(out, " & ProcessKCentre - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_MAdjust].defined) fprintf(out, " & ProcessKRight - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_Break].defined) fprintf(out, " & ProcessKBreak - SpecialCodeTable%d\n", kb->country); for (i=0; i<17; i++) fprintf(out, " & ProcessK1Pad - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_ScrollLock].defined) fprintf(out, " & ProcessKScroll - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_NumLock].defined) fprintf(out, " & ProcessKNum - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_Tab].defined) fprintf(out, " & ProcessKTab - SpecialCodeTable%d\n", kb->country); if (!kb->key[K_CapsLock].defined) fprintf(out, " & ProcessKCaps - SpecialCodeTable%d\n", kb->country); for (i=0; ikey[i].defined && !kb->key[i].easy) fprintf(out, " & ProcessUCS - SpecialCodeTable%d\n", kb->country); } if (kb->needshiftinglist) { fprintf(out, "\nShiftingKeyList%d\n" " = ShiftingKeyList%dEnd - ShiftingKeyList%d - 1\n", kb->country, kb->country, kb->country); if (!kb->key[K_ShiftL].defined) fprintf(out, " = K1ShiftLeft\n"); if (!kb->key[K_ShiftR].defined) fprintf(out, " = K1ShiftRight\n"); if (!kb->key[K_CtrlL].defined) fprintf(out, " = K1CtrlLeft\n"); if (!kb->key[K_CtrlR].defined) fprintf(out, " = K1CtrlRight\n"); if (!kb->key[K_AltL].defined) fprintf(out, " = K1AltLeft\n"); if (!kb->key[K_AltR].defined) fprintf(out, " = K1AltRight\n"); if (!kb->key[K_FN].defined) fprintf(out, " = K1FN\n"); if (!kb->key[K_MAdjust].defined) fprintf(out, " = K1RightMouse\n"); if (!kb->key[K_MMenu].defined) fprintf(out, " = K1CentreMouse\n"); if (!kb->key[K_MSelect].defined) fprintf(out, " = K1LeftMouse\n"); if (!kb->key[K_Break].defined) fprintf(out, " = K1Break\n"); fprintf(out, "ShiftingKeyList%dEnd\n", kb->country); } for (i=0; ilayers; i++) output_layer(out, kb, i); if (kb->fnused) { fprintf(out, "\nFNTable%d\n" " = (FNTable%dEnd - FNTable%d - 1) / 2\n", kb->country, kb->country, kb->country); for (i=0; ikey[i].fn != -1) { if (!kb->key[i].tablenum || !kb->key[kb->key[i].fn].tablenum) { char buffer[128]; sprintf(buffer, "Consistency failure in FN map (%02X->%02X)", i, kb->key[i].fn); error(buffer); } fprintf(out, " = &%02X, &%02X\n", kb->key[i].tablenum, kb->key[kb->key[i].fn].tablenum); } fprintf(out, "FNTable%dEnd\n", kb->country); } if (kb->custompad) { int j, n; for (n=0; n<=1; n++) { fprintf(out, n ? "\nPadK%dCurTran" : "\nPadK%dNumTran", kb->country); for (j=0, i=0; i<17; i++) { fprintf(out, "%s&%02X", j==0 ? "\n = " : ", ", kb->keypad[n][i]); j = (j+1)%8; } } putc('\n', out); } fprintf(out, "\n ALIGN\n"); fprintf(out, "\n END\n"); } int main(int argc, char **argv) { FILE *in, *out; if (argc >= 3 && strcmp(argv[1], "-depend")==0) { depend = 1; dependfilename = argv[2]; argv+=2; argc-=2; } if (argc >= 2 && strcmp(argv[1], "-throwback")==0) { throwback = 1; argv++; argc--; } if (argc >= 3 && strcmp(argv[1], "-extra")==0) { ExtraKeys = argv[2]; argv+=2; argc-=2; } if (argc >= 3 && strcmp(argv[1], "-fn")==0) { FNKey = argv[2]; argv+=2; argc-=2; } if (argc != 3) { fprintf(stderr, "Usage: keygen [-depend filename] [-throwback] [-extra filename] [-fn filename]\n" " layout-file output-file\n"); exit(1); } in = fopen(argv[1], "r"); if (!in) { perror(argv[1]); exit(1); } out = fopen(argv[2], "w"); if (!out) { perror(argv[2]); exit(1); } sourcefilename[0] = argv[1]; current_output_handle = out; current_output_file = argv[2]; if (depend) add_dependency(current_output_file, sourcefilename[0]); load_unidata("UniData215"); process_keyboard(in, out); return 0; }