Here is a hacked version of canvas_key that makes keyname generate symbols that all start with "key-". I'm not sure of the legality of having non alphanumeric characters in symbols, but they're there. This hack also gets non-printing characters as names, so you can get Space, Tab, etc. out of keyname. I hope this hack gets incorporated, or that a better solution is found.
P.S. The comment above this function has bugs, but I'm not sure how to fix them.
void canvas_key(t_canvas *x, t_symbol *s, int ac, t_atom *av) { static t_symbol *keynumsym, *keyupsym, *keynamesym; float keynum, fflag; if (ac < 2) return; fflag = (av[0].a_type == A_FLOAT ? av[0].a_w.w_float : 0); keynum = (av[1].a_type == A_FLOAT ? av[1].a_w.w_float : 0); if (keynum == '\' || keynum == '{' || keynum == '}') { post("%c: dropped", (int)keynum); return; } if (keynum == '\r') keynum = '\n'; /* post("key %c", keynum); */ if (av[1].a_type == A_SYMBOL && !strcmp(av[1].a_w.w_symbol->s_name, "Return")) keynum = '\n'; if (!keynumsym) { keynumsym = gensym("#key"); keyupsym = gensym("#keyup"); keynamesym = gensym("#keyname"); } if (keynumsym->s_thing && (fflag != 0)) pd_float(keynumsym->s_thing, keynum); if (keyupsym->s_thing && (fflag == 0)) pd_float(keyupsym->s_thing, keynum); if (keynamesym->s_thing) { char buf[128]; /* XXX */ t_atom at[2]; at[0] = av[0]; if (av[1].a_type == A_SYMBOL) { at[1] = av[1]; sprintf(buf, "key-%s", av[1].a_w.w_symbol->s_name); /* post("SYMBOL %d", (int) av[1].a_w.w_symbol->s_name[0]); */ } else { if ((int)(av[1].a_w.w_float) == 127) { sprintf(buf, "key-Delete"); } else if ((int)(av[1].a_w.w_float) == 32) { sprintf(buf, "key-Space"); } else if ((int)(av[1].a_w.w_float) == 27) { sprintf(buf, "key-Esc"); } else if ((int)(av[1].a_w.w_float) == 13) { sprintf(buf, "key-Enter"); } else if ((int)(av[1].a_w.w_float) == 9) { sprintf(buf, "key-Tab"); } else if ((int)(av[1].a_w.w_float) == 8) { sprintf(buf, "key-Backspace"); } else { sprintf(buf, "key-%c", (int)(av[1].a_w.w_float)); /* post("NUMBER %d", (int) av[1].a_w.w_float); */ } } /* post("OUT %s", buf); */ SETSYMBOL(at+1, gensym(buf)); pd_list(keynamesym->s_thing, 0, 2, at); } if (x && (fflag != 0)) { if (!x->gl_editor) { bug("editor"); return; } /* if an object has "grabbed" keys just send them on */ if (x->gl_editor->e_grab && (keynum != 0) && x->gl_editor->e_keyfn) (* x->gl_editor->e_keyfn) (x->gl_editor->e_grab, keynum); /* if a text editor is open send it on */ else if (x->gl_editor->e_textedfor) { rtext_key(x->gl_editor->e_textedfor, (int)keynum, (av[1].a_type == A_SYMBOL ? av[1].a_w.w_symbol : &s_)); if (x->gl_editor->e_textdirty) canvas_dirty(x, 1); } /* otherwise check for backspace or clear and do so */ else if (keynum == 8 || keynum == 127) canvas_doclear(x); } }