static void print_key(TermKey *tk, TermKeyKey *key) { switch(key->type) { case TERMKEY_TYPE_UNICODE: fprintf(stderr, "Unicode codepoint=U+%04lx utf8='%s'", key->code.codepoint, key->utf8); break; case TERMKEY_TYPE_FUNCTION: fprintf(stderr, "Function F%d", key->code.number); break; case TERMKEY_TYPE_KEYSYM: fprintf(stderr, "Keysym sym=%d(%s)", key->code.sym, termkey_get_keyname(tk, key->code.sym)); break; case TERMKEY_TYPE_MOUSE: { TermKeyMouseEvent ev; int button, line, col; termkey_interpret_mouse(tk, key, &ev, &button, &line, &col); fprintf(stderr, "Mouse ev=%d button=%d pos=(%d,%d)\n", ev, button, line, col); } break; case TERMKEY_TYPE_POSITION: { int line, col; termkey_interpret_position(tk, key, &line, &col); fprintf(stderr, "Position report pos=(%d,%d)\n", line, col); } break; case TERMKEY_TYPE_MODEREPORT: { int initial, mode, value; termkey_interpret_modereport(tk, key, &initial, &mode, &value); fprintf(stderr, "Mode report mode=%s %d val=%d\n", initial == '?' ? "DEC" : "ANSI", mode, value); } break; case TERMKEY_TYPE_DCS: fprintf(stderr, "Device Control String"); break; case TERMKEY_TYPE_OSC: fprintf(stderr, "Operating System Control"); break; case TERMKEY_TYPE_UNKNOWN_CSI: fprintf(stderr, "unknown CSI\n"); break; } int m = key->modifiers; fprintf(stderr, " mod=%s%s%s+%02x", (m & TERMKEY_KEYMOD_CTRL ? "C" : ""), (m & TERMKEY_KEYMOD_ALT ? "A" : ""), (m & TERMKEY_KEYMOD_SHIFT ? "S" : ""), m & ~(TERMKEY_KEYMOD_CTRL|TERMKEY_KEYMOD_ALT|TERMKEY_KEYMOD_SHIFT)); }
size_t termkey_strfkey(TermKey *tk, char *buffer, size_t len, TermKeyKey *key, TermKeyFormat format) { size_t pos = 0; size_t l = 0; struct modnames *mods = &modnames[!!(format & TERMKEY_FORMAT_LONGMOD) + !!(format & TERMKEY_FORMAT_ALTISMETA) * 2 + !!(format & TERMKEY_FORMAT_LOWERMOD) * 4]; int wrapbracket = (format & TERMKEY_FORMAT_WRAPBRACKET) && (key->type != TERMKEY_TYPE_UNICODE || key->modifiers != 0); char sep = (format & TERMKEY_FORMAT_SPACEMOD) ? ' ' : '-'; if(format & TERMKEY_FORMAT_CARETCTRL && key->type == TERMKEY_TYPE_UNICODE && key->modifiers == TERMKEY_KEYMOD_CTRL) { long codepoint = key->code.codepoint; // Handle some of the special casesfirst if(codepoint >= 'a' && codepoint <= 'z') { l = snprintf(buffer + pos, len - pos, wrapbracket ? "<^%c>" : "^%c", (char)codepoint - 0x20); if(l <= 0) return pos; pos += l; return pos; } else if((codepoint >= '@' && codepoint < 'A') || (codepoint > 'Z' && codepoint <= '_')) { l = snprintf(buffer + pos, len - pos, wrapbracket ? "<^%c>" : "^%c", (char)codepoint); if(l <= 0) return pos; pos += l; return pos; } } if(wrapbracket) { l = snprintf(buffer + pos, len - pos, "<"); if(l <= 0) return pos; pos += l; } if(key->modifiers & TERMKEY_KEYMOD_ALT) { l = snprintf(buffer + pos, len - pos, "%s%c", mods->alt, sep); if(l <= 0) return pos; pos += l; } if(key->modifiers & TERMKEY_KEYMOD_CTRL) { l = snprintf(buffer + pos, len - pos, "%s%c", mods->ctrl, sep); if(l <= 0) return pos; pos += l; } if(key->modifiers & TERMKEY_KEYMOD_SHIFT) { l = snprintf(buffer + pos, len - pos, "%s%c", mods->shift, sep); if(l <= 0) return pos; pos += l; } switch(key->type) { case TERMKEY_TYPE_UNICODE: if(!key->utf8[0]) // In case of user-supplied key structures fill_utf8(key); l = snprintf(buffer + pos, len - pos, "%s", key->utf8); break; case TERMKEY_TYPE_KEYSYM: { const char *name = termkey_get_keyname(tk, key->code.sym); if(format & TERMKEY_FORMAT_LOWERSPACE) l = snprint_cameltospaces(buffer + pos, len - pos, name); else l = snprintf(buffer + pos, len - pos, "%s", name); } break; case TERMKEY_TYPE_FUNCTION: l = snprintf(buffer + pos, len - pos, "%c%d", (format & TERMKEY_FORMAT_LOWERSPACE ? 'f' : 'F'), key->code.number); break; case TERMKEY_TYPE_MOUSE: { TermKeyMouseEvent ev; int button; int line, col; termkey_interpret_mouse(tk, key, &ev, &button, &line, &col); static const char *evnames[] = { "Unknown", "Press", "Drag", "Release" }; l = snprintf(buffer + pos, len - pos, "Mouse%s(%d)", evnames[ev], button); if(format & TERMKEY_FORMAT_MOUSE_POS) { if(l <= 0) return pos; pos += l; l = snprintf(buffer + pos, len - pos, " @ (%u,%u)", col, line); } } break; case TERMKEY_TYPE_POSITION: l = snprintf(buffer + pos, len - pos, "Position"); break; case TERMKEY_TYPE_MODEREPORT: { int initial, mode, value; termkey_interpret_modereport(tk, key, &initial, &mode, &value); if(initial) l = snprintf(buffer + pos, len - pos, "Mode(%c%d=%d)", initial, mode, value); else l = snprintf(buffer + pos, len - pos, "Mode(%d=%d)", mode, value); } case TERMKEY_TYPE_UNKNOWN_CSI: l = snprintf(buffer + pos, len - pos, "CSI %c", key->code.number & 0xff); break; } if(l <= 0) return pos; pos += l; if(wrapbracket) { l = snprintf(buffer + pos, len - pos, ">"); if(l <= 0) return pos; pos += l; } return pos; }
int main(int argc, char *argv[]) { TERMKEY_CHECK_VERSION; int mouse = 0; int mouse_proto = 0; TermKeyFormat format = TERMKEY_FORMAT_VIM; char buffer[50]; TermKey *tk; int opt; while((opt = getopt(argc, argv, "m::p:")) != -1) { switch(opt) { case 'm': if(optarg) mouse = atoi(optarg); else mouse = 1000; break; case 'p': mouse_proto = atoi(optarg); break; default: fprintf(stderr, "Usage: %s [-m]\n", argv[0]); return 1; } } tk = termkey_new(0, TERMKEY_FLAG_SPACESYMBOL|TERMKEY_FLAG_CTRLC); if(!tk) { fprintf(stderr, "Cannot allocate termkey instance\n"); exit(1); } TermKeyResult ret; TermKeyKey key; if(mouse) { printf("\033[?%dhMouse mode active\n", mouse); if(mouse_proto) printf("\033[?%dh", mouse_proto); } while((ret = termkey_waitkey(tk, &key)) != TERMKEY_RES_EOF) { if(ret == TERMKEY_RES_KEY) { termkey_strfkey(tk, buffer, sizeof buffer, &key, format); if(key.type == TERMKEY_TYPE_MOUSE) { int line, col; termkey_interpret_mouse(tk, &key, NULL, NULL, &line, &col); printf("%s at line=%d, col=%d)\n", buffer, line, col); } else if(key.type == TERMKEY_TYPE_POSITION) { int line, col; termkey_interpret_position(tk, &key, &line, &col); printf("Cursor position report at line=%d, col=%d)\n", line, col); } else { printf("%s\n", buffer); } if(key.type == TERMKEY_TYPE_UNICODE && key.modifiers & TERMKEY_KEYMOD_CTRL && (key.code.codepoint == 'C' || key.code.codepoint == 'c')) break; if(key.type == TERMKEY_TYPE_UNICODE && key.modifiers == 0 && key.code.codepoint == '?') { printf("\033[6n"); fflush(stdout); } } else if(ret == TERMKEY_RES_ERROR) { if(errno != EINTR) { perror("termkey_waitkey"); break; } printf("Interrupted by signal\n"); } } if(mouse) printf("\033[?%dlMouse mode deactivated\n", mouse); termkey_destroy(tk); }