diff --git a/src/console/ptyc_console_reader.c b/src/console/ptyc_console_reader.c index 3afab13..0ce4900 100644 --- a/src/console/ptyc_console_reader.c +++ b/src/console/ptyc_console_reader.c @@ -12,8 +12,162 @@ #include #include "ptycon_driver_impl.h" +typedef nt_unicode_conversion_params_utf16_to_utf8 uc_conv_params; + +static size_t ptyc_translate_keyboard_event( + nt_input_record * rec, + unsigned char * ch, + wchar16_t * wch) +{ + wchar16_t src[2]; + wchar16_t recwch; + uint32_t nbytes; + uc_conv_params params = {0,0,0,0,0,0,0,0,0}; + + if (!rec->key_event.key_down) + return 0; + + if (!(recwch = rec->key_event.unicode_char)) + return 0; + + if (*wch) { + if ((recwch < 0xDC00) || (recwch >= 0xE000)) { + *wch = 0; + return 0; + } else { + src[0] = *wch; + src[1] = recwch; + *wch = 0; + nbytes = 2*sizeof(wchar16_t); + } + } else if ((recwch >= 0xD800) && (recwch < 0xDC00)) { + *wch = recwch; + return 0; + + } else { + src[0] = recwch; + nbytes = sizeof(wchar16_t); + } + + params.src = src; + params.src_size_in_bytes = nbytes; + params.dst = ch; + params.dst_size_in_bytes = 4; + + ntapi->uc_convert_unicode_stream_utf16_to_utf8( + ¶ms); + + return params.bytes_written; +} + +static size_t ptyc_translate_mouse_event( + nt_input_record * rec, + unsigned char * ch) +{ + (void)rec; + (void)ch; + return 0; +} + +static size_t ptyc_translate_window_event(nt_input_record * rec) +{ + (void)rec; + return 0; +} + +static size_t ptyc_translate_menu_event(nt_input_record * rec) +{ + (void)rec; + return 0; +} + +static size_t ptyc_translate_focus_event(nt_input_record * rec) +{ + (void)rec; + return 0; +} + +static size_t ptyc_translate_event( + nt_input_record * rec, + unsigned char * ch, + wchar16_t * wch) +{ + switch (rec->event_type) { + case NT_KEY_EVENT: + return ptyc_translate_keyboard_event( + rec,ch,wch); + + case NT_MOUSE_EVENT: + return ptyc_translate_mouse_event( + rec,ch); + + case NT_WINDOW_BUFFER_SIZE_EVENT: + return ptyc_translate_window_event(rec); + + case NT_MENU_EVENT: + return ptyc_translate_menu_event(rec); + + case NT_FOCUS_EVENT: + return ptyc_translate_focus_event(rec); + } + + return 0; +} + int ptyc_console_reader(struct ptyc_driver_ctx_impl * ictx) { - (void)ictx; - return ntapi->tt_wait_for_dummy_event(); + int32_t status; + void * hwait; + nt_iosb iosb; + uint32_t nevents; + size_t nbytes; + wchar16_t wch; + unsigned char * ch; + unsigned i; + + if ((status = ntapi->tt_create_private_event( + &hwait, + NT_NOTIFICATION_EVENT, + NT_EVENT_NOT_SIGNALED))) + return status; + + do { + if (!(ntcon->read_console_input_utf16( + ictx->tctx.hin, + ictx->tctx.input.events, + PTYC_RAW_EVENTS, + &nevents))) + return NT_STATUS_ALREADY_DISCONNECTED; + + for (ch=ictx->tctx.input.stream, i=0; itctx.input.events[i], + ch,&wch); + + nbytes = ch - ictx->tctx.input.stream; + ch = ictx->tctx.input.stream; + + for (; nbytes; ) { + status = ntapi->pty_write( + ictx->cctx.hptm, + hwait,0,0, + &iosb, + ch,nbytes, + 0,0); + + if (status == NT_STATUS_PENDING) + status = ntapi->zw_wait_for_single_object( + hwait,NT_SYNC_ALERTABLE,0); + + if (status || iosb.status) { + ntapi->zw_close(hwait); + return status ? status : iosb.status; + } + + ch += iosb.info; + nbytes -= iosb.info; + } + } while (1); + + return NT_STATUS_INTERNAL_ERROR; } diff --git a/src/internal/ptycon_bridge_impl.h b/src/internal/ptycon_bridge_impl.h index a9d255c..279ce07 100644 --- a/src/internal/ptycon_bridge_impl.h +++ b/src/internal/ptycon_bridge_impl.h @@ -2,6 +2,7 @@ #define PTYCON_BRIDGE_IMPL_H #include +#include enum ptyc_ctrl_state { PTYC_CTRL_STATE_ESI, @@ -11,6 +12,7 @@ enum ptyc_ctrl_state { }; #define PTYC_BUFFER_ELEMENTS 0x8000 +#define PTYC_RAW_EVENTS 0x400 #define PTYC_CTRL_PARAMS 0x20 #define PTYC_ESI_ARRAY_SIZE 0x5F @@ -24,6 +26,11 @@ struct ptyc_term_data { wchar16_t screen [PTYC_BUFFER_ELEMENTS]; }; +struct ptyc_term_input { + nt_input_record events [PTYC_RAW_EVENTS]; + unsigned char stream [PTYC_RAW_EVENTS*4]; +}; + struct ptyc_term_ctx; typedef void * __fastcall ptyc_term_handler (struct ptyc_term_ctx *); @@ -47,6 +54,7 @@ struct ptyc_term_ctx { uint16_t foreground; uint16_t background; struct ptyc_term_data data; + struct ptyc_term_input input; }; extern ptyc_term_handler * const ptyc_esi_handlers[];