/* Merged parser stuff for keyboard plugin */ %{ /* for unicode keyboard plugin */ static void keyb_mod(int wich, t_keysym keynum, int unicode); static void dump_keytable_part(FILE *f, t_keysym *map, int size); %} /* special bison declaration */ %token UNICODE %token SHIFT_ALT_MAP CTRL_MAP CTRL_ALT_MAP %% keyboard_mod : CTRL_MAP expression '=' { keyb_mod('C', $2, 0); } keyboard_modvals | SHIFT_ALT_MAP expression '=' { keyb_mod('a', $2, 0); } keyboard_modvals | CTRL_ALT_MAP expression '=' { keyb_mod('c', $2, 0); } keyboard_modvals ; keyboard_modval : UNICODE { keyb_mod(0, $1, 1); } | DGRAVE { keyb_mod(0, DKY_DEAD_GRAVE, 1); } | DACUTE { keyb_mod(0, DKY_DEAD_ACUTE, 1); } | DCIRCUM { keyb_mod(0, DKY_DEAD_CIRCUMFLEX, 1); } | DTILDE { keyb_mod(0, DKY_DEAD_TILDE, 1); } | DBREVE { keyb_mod(0, DKY_DEAD_BREVE, 1); } | DABOVED { keyb_mod(0, DKY_DEAD_ABOVEDOT, 1); } | DDIARES { keyb_mod(0, DKY_DEAD_DIAERESIS, 1); } | DABOVER { keyb_mod(0, DKY_DEAD_ABOVERING, 1); } | DDACUTE { keyb_mod(0, DKY_DEAD_DOUBLEACUTE, 1); } | DCEDILLA { keyb_mod(0, DKY_DEAD_CEDILLA, 1); } | DIOTA { keyb_mod(0, DKY_VOID, 1); } /* no dead iotas exist */ | DOGONEK { keyb_mod(0,DKY_DEAD_OGONEK, 1); } | DCARON { keyb_mod(0, DKY_DEAD_CARON, 1); } ; %% /* for keyboard plugin */ static void keyb_mod(int wich, t_keysym keynum, int unicode) { static t_keysym *table = 0; static int count = 0; if (wich == ' ') { switch (keynum & 0xFF00) { case 0x000: wich = ' '; break; case 0x100: wich = 'S'; break; case 0x200: wich = 'A'; break; case 0x300: wich = 'N'; break; case 0x400: wich = 'C'; break; case 0x500: wich = 'a'; break; case 0x600: wich = 'c'; break; default: /* It's a bad value ditch it */ wich ='X'; table = 0; count = 0; break; } keynum &= 0xFF; } switch (wich) { case ' ': table = config.keytable->key_map; count=config.keytable->sizemap; break; case 'S': table = config.keytable->shift_map; count=config.keytable->sizemap; break; case 'A': table = config.keytable->alt_map; count=config.keytable->sizemap; break; case 'C': table = config.keytable->ctrl_map; count=config.keytable->sizemap; break; case 'a': table = config.keytable->shift_alt_map; count=config.keytable->sizemap; break; case 'c': table = config.keytable->ctrl_alt_map; count=config.keytable->sizemap; break; case 'N': table = config.keytable->num_table; count=config.keytable->sizepad; break; } if (!table || (count == 0) || (wich != 0 && keynum >= count)) { count = 0; table = 0; return; } if (wich != 0) { table += keynum; count -= keynum; return; } if (!unicode) { if (keynum == 0) { keynum = DKY_VOID; } else { keynum = keynum + 0xEF00; } } if (count > 0) { *table++ = keynum; count--; } } static char *get_key_name(t_keysym key) { struct key_names { t_keysym key; char *name; }; static struct key_names names[] = { { DKY_DEAD_GRAVE, "dgrave"}, { DKY_DEAD_ACUTE, "dacute"}, { DKY_DEAD_CIRCUMFLEX, "dcircum"}, { DKY_DEAD_TILDE, "dtilde"}, { DKY_DEAD_BREVE, "dbreve"}, { DKY_DEAD_ABOVEDOT, "daboved"}, { DKY_DEAD_DIAERESIS, "ddiares"}, { DKY_DEAD_ABOVERING, "dabover"}, { DKY_DEAD_DOUBLEACUTE, "ddacute"}, { DKY_DEAD_CEDILLA, "dcedilla"}, { DKY_DEAD_OGONEK, "dogonek"}, { DKY_DEAD_CARON, "dcaron"}, }; int i; for(i = 0; i < sizeof(names)/sizeof(names[0]); i++) { if (names[i].key == key) { return names[i].name; } } return 0; } static void dump_keytable_part(FILE *f, t_keysym *map, int size) { int i, in_string=0; t_keysym c; char *cc, comma=' ', buf[16]; /* Note: This code assumes every font is a superset of ascii */ if (!map) { return; } size--; for (i=0; i<=size; i++) { c = map[i]; if (!(i & 15)) fprintf(f," "); cc = get_key_name(c); if (!cc && (c < 128) && isprint(c) && !strchr("\\\"\'`", c)) { if (in_string) fputc(c,f); else { fprintf(f, "%c\"%c", comma, c); in_string = 1; } } else { if (!cc) { if (((c > 0) && (c < 128)) || ((c >= 0xEF00) && (c <= 0xEFFF))) { sprintf(buf, "%d", c & 0xFF); } else if (c == DKY_VOID) { strcpy(buf, "0"); } else { sprintf(buf, "\\u%04x", c); } cc = buf; } if (!in_string) fprintf(f, "%c%s", comma, cc); else { fprintf(f, "\",%s", cc); in_string = 0; } } if ((i & 15) == 15) { if (in_string) fputc('"', f); if (i < size) fputc(',', f); fputc('\n', f); in_string = 0; comma = ' '; } else comma = ','; } if (in_string) fputc('"', f); fputc('\n', f); } void dump_keytable(FILE *f, struct keytable_entry *kt) { fprintf(f, "keytable %s {\n", kt->name); fprintf(f, " 0=\n"); dump_keytable_part(f, kt->key_map, kt->sizemap); fprintf(f, " shift 0=\n"); dump_keytable_part(f, kt->shift_map, kt->sizemap); fprintf(f, " alt 0=\n"); dump_keytable_part(f, kt->alt_map, kt->sizemap); fprintf(f, " numpad 0=\n"); dump_keytable_part(f, kt->num_table, kt->sizepad-1); fprintf(f, " ctrl 0=\n"); dump_keytable_part(f, kt->ctrl_map, kt->sizemap); fprintf(f, " shift-alt 0=\n"); dump_keytable_part(f, kt->shift_alt_map, kt->sizemap); fprintf(f, " ctrl-alt 0=\n"); dump_keytable_part(f, kt->ctrl_alt_map, kt->sizemap); fprintf(f, "}\n\n\n"); }