#ifdef __GLIBC__ # define _XOPEN_SOURCE 500 // usleep #endif #include "tickit.h" #include "taplib.h" #include #include TickitKeyEventType keytype; char keystr[16]; int keymod; int on_key_return = 1; int on_key(TickitTerm *tt, TickitEventFlags flags, void *_info, void *data) { TickitKeyEventInfo *info = _info; keytype = info->type; strncpy(keystr, info->str, sizeof(keystr)-1); keystr[sizeof(keystr)-1] = 0; keymod = info->mod; return on_key_return; } int on_key_incr(TickitTerm *tt, TickitEventFlags flags, void *_info, void *data) { (*(int *)data)++; return 1; } TickitMouseEventType mousetype; int mousebutton, mouseline, mousecol; int mousemod; int on_mouse(TickitTerm *tt, TickitEventFlags flags, void *_info, void *data) { TickitMouseEventInfo *info = _info; mousetype = info->type; mousebutton = info->button; mouseline = info->line; mousecol = info->col; mousemod = info->mod; return 1; } char events[2]; uint8_t i = 0; int on_key_push(TickitTerm *tt, TickitEventFlags flags, void *info, void *user) { events[i++] = *(char*)user; return 0; } int main(int argc, char *argv[]) { TickitTerm *tt; tt = tickit_term_build(&(struct TickitTermBuilder){ .termtype = "xterm", }); tickit_term_set_utf8(tt, 1); ok(tickit_term_get_utf8(tt), "get_utf8 true"); tickit_term_bind_event(tt, TICKIT_TERM_ON_KEY, 0, on_key, NULL); tickit_term_bind_event(tt, TICKIT_TERM_ON_MOUSE, 0, on_mouse, NULL); { TickitKeyEventInfo info = { .type = TICKIT_KEYEV_TEXT, .mod = 0, .str = " ", }; tickit_term_emit_key(tt, &info); is_int(keytype, TICKIT_KEYEV_TEXT, "keytype after emit_key"); is_str(keystr, " ", "keystr after emit_key"); is_int(keymod, 0, "keymod after emit_key"); } tickit_term_input_push_bytes(tt, "A", 1); is_int(keytype, TICKIT_KEYEV_TEXT, "keytype after push_bytes A"); is_str(keystr, "A", "keystr after push_bytes A"); is_int(keymod, 0, "keymod after push_bytes A"); is_int(tickit_term_input_check_timeout_msec(tt), -1, "term has no timeout after A"); /* U+0109 - LATIN SMALL LETTER C WITH CIRCUMFLEX * UTF-8: 0xc4 0x89 */ tickit_term_input_push_bytes(tt, "\xc4\x89", 2); is_int(keytype, TICKIT_KEYEV_TEXT, "keytype after push_bytes U+0109"); is_str(keystr, "\xc4\x89", "keystr after push_bytes U+0109"); is_int(keymod, 0, "keymod after push_bytes U+0109"); tickit_term_input_push_bytes(tt, "\e[A", 3); is_int(keytype, TICKIT_KEYEV_KEY, "keytype after push_bytes Up"); is_str(keystr, "Up", "keystr after push_bytes Up"); is_int(keymod, 0, "keymod after push_bytes Up"); tickit_term_input_push_bytes(tt, "\x01", 1); is_int(keytype, TICKIT_KEYEV_KEY, "keytype after push_bytes C-a"); is_str(keystr, "C-a", "keystr after push_bytes C-a"); is_int(keymod, TICKIT_MOD_CTRL, "keymod after push_bytes C-a"); is_int(tickit_term_input_check_timeout_msec(tt), -1, "term has no timeout after Up"); { TickitMouseEventInfo info = { .type = TICKIT_MOUSEEV_PRESS, .button = 1, .line = 2, .col = 3, .mod = 0, }; tickit_term_emit_mouse(tt, &info); is_int(mousetype, TICKIT_MOUSEEV_PRESS, "mousetype after emit_mouse"); is_int(mousebutton, 1, "mousebutton after emit_mouse"); is_int(mouseline, 2, "mouseline after emit_mouse"); is_int(mousecol, 3, "mousecol after emit_mouse"); } tickit_term_input_push_bytes(tt, "\e[M !!", 6); is_int(mousetype, TICKIT_MOUSEEV_PRESS, "mousetype after mouse button press"); is_int(mousebutton, 1, "mousebutton after mouse button press"); is_int(mouseline, 0, "mouseline after mouse button press"); is_int(mousecol, 0, "mousecol after mouse button press"); is_int(mousemod, 0, "mousemod after mouse button press"); tickit_term_input_push_bytes(tt, "\e[M#!!", 6); is_int(mousetype, TICKIT_MOUSEEV_RELEASE, "mousetype after mouse button release"); is_int(mousebutton, 1, "mousebutton after mouse button release"); is_int(mouseline, 0, "mouseline after mouse button release"); is_int(mousecol, 0, "mousecol after mouse button release"); is_int(mousemod, 0, "mousemod after mouse button release"); tickit_term_input_push_bytes(tt, "\e[M`!!", 6); is_int(mousetype, TICKIT_MOUSEEV_WHEEL, "mousetype after mouse wheel up"); is_int(mousebutton, TICKIT_MOUSEWHEEL_UP, "mousebutton after mouse wheel up"); is_int(mouseline, 0, "mouseline after mouse wheel up"); is_int(mousecol, 0, "mousecol after mouse wheel up"); is_int(mousemod, 0, "mousemod after mouse wheel up"); keytype = -1; keystr[0] = 0; tickit_term_input_push_bytes(tt, "\e[", 2); is_int(keytype, -1, "keytype not set after push_bytes partial Down"); ok(tickit_term_input_check_timeout_msec(tt) > 0, "term has timeout after partial Down"); tickit_term_input_push_bytes(tt, "B", 1); is_int(keytype, TICKIT_KEYEV_KEY, "keytype after push_bytes completed Down"); is_str(keystr, "Down", "keystr after push_bytes completed Down"); is_int(tickit_term_input_check_timeout_msec(tt), -1, "term has no timeout after completed Down"); keytype = -1; keystr[0] = 0; tickit_term_input_push_bytes(tt, "\e", 1); is_int(keytype, -1, "keytype not set after push_bytes Escape"); int msec = tickit_term_input_check_timeout_msec(tt); ok(msec > 0, "term has timeout after Escape"); /* Add an extra milisecond timing grace */ usleep((msec+1) * 1000); tickit_term_input_check_timeout_msec(tt); is_int(keytype, TICKIT_KEYEV_KEY, "keytype after push_bytes completed Escape"); is_str(keystr, "Escape", "keystr after push_bytes completed Escape"); is_int(tickit_term_input_check_timeout_msec(tt), -1, "term has no timeout after completed Escape"); { int count = 0; int bind_id = tickit_term_bind_event(tt, TICKIT_TERM_ON_KEY, 0, &on_key_incr, &count); keytype = -1; on_key_return = 1; tickit_term_input_push_bytes(tt, "A", 1); is_int(keytype, TICKIT_KEYEV_TEXT, "keytype after push bytes with two events bound"); is_int(count, 0, "count of second event binding after first event with return 1"); keytype = -1; on_key_return = 0; tickit_term_input_push_bytes(tt, "A", 1); is_int(keytype, TICKIT_KEYEV_TEXT, "keytype after push bytes with two events bound the second time"); is_int(count, 1, "count of second event binding after first event with return 0"); tickit_term_unbind_event_id(tt, bind_id); } { int bindA_id = tickit_term_bind_event(tt, TICKIT_TERM_ON_KEY, 0, &on_key_push, "A"); int bindB_id = tickit_term_bind_event(tt, TICKIT_TERM_ON_KEY, TICKIT_BIND_FIRST, &on_key_push, "B"); tickit_term_input_push_bytes(tt, "X", 1); is_int(i, 2, "two events fired"); is_int(events[0], 'B', "TICKIT_BIND_FIRST event fired first"); tickit_term_unbind_event_id(tt, bindA_id); tickit_term_unbind_event_id(tt, bindB_id); } tickit_term_unref(tt); return exit_status(); }