diff options
Diffstat (limited to 'src/console')
-rw-r--r-- | src/console/ptyc_console_reader.c | 158 |
1 files changed, 156 insertions, 2 deletions
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 <ptycon/ptycon.h> #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; i<nevents; i++) + ch += ptyc_translate_event( + &ictx->tctx.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; } |