diff --git a/include/ptycon/ptycon.h b/include/ptycon/ptycon.h index 930dd57..633302b 100644 --- a/include/ptycon/ptycon.h +++ b/include/ptycon/ptycon.h @@ -75,6 +75,11 @@ ptyc_api void ptyc_free_driver_ctx (struct ptyc_driver_ctx *); ptyc_api int ptyc_alloc_pty (struct ptyc_driver_ctx *); ptyc_api void ptyc_free_pty (struct ptyc_driver_ctx *); +/* console api */ +ptyc_api int ptyc_alloc_console (struct ptyc_driver_ctx *); +ptyc_api int ptyc_wait_for_console (struct ptyc_driver_ctx *); +ptyc_api void ptyc_free_console (struct ptyc_driver_ctx *); + /* utility api */ ptyc_api int ptyc_main (int, char **, char **); diff --git a/project/common.mk b/project/common.mk index 3b490d4..1e54767 100644 --- a/project/common.mk +++ b/project/common.mk @@ -1,4 +1,12 @@ COMMON_SRCS = \ + src/console/ptyc_console_alloc.c \ + src/console/ptyc_console_ctrl.c \ + src/console/ptyc_console_poller.c \ + src/console/ptyc_console_reader.c \ + src/console/ptyc_console_writer.c \ + src/debug/ptyc_dbg_event.c \ + src/debug/ptyc_dbg_oven.c \ + src/debug/ptyc_dbg_raw.c \ src/driver/ptyc_amain.c \ src/driver/ptyc_driver_ctx.c \ src/internal/gdi/gdi.c \ diff --git a/project/tree.mk b/project/tree.mk index 07f4d48..535fde1 100644 --- a/project/tree.mk +++ b/project/tree.mk @@ -1,5 +1,7 @@ tree.tag: mkdir -p src + mkdir -p src/console + mkdir -p src/debug mkdir -p src/driver mkdir -p src/internal mkdir -p src/internal/gdi diff --git a/src/console/ptyc_console_alloc.c b/src/console/ptyc_console_alloc.c new file mode 100644 index 0000000..16d1f80 --- /dev/null +++ b/src/console/ptyc_console_alloc.c @@ -0,0 +1,220 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" +#include "ptycon_status_impl.h" + +int ptyc_console_ctrl(uint32_t); + +int ptyc_console_reader(void *); +int ptyc_console_writer(void *);; +int ptyc_console_poller(void *); + +int ptyc_dbg_event(void *); +int ptyc_dbg_oven(void *); +int ptyc_dbg_raw(void *); + +struct ptyc_loop_thread_ctx { + nt_thread_start_routine * entry; + struct ptyc_driver_ctx_impl * ictx; +}; + +static int ptyc_loop_thread_entry(void * ctx) +{ + struct ptyc_loop_thread_ctx * xctx; + + xctx = (struct ptyc_loop_thread_ctx *)ctx; + + return ntapi->zw_terminate_thread( + NT_CURRENT_THREAD_HANDLE, + xctx->entry(xctx->ictx)); +} + +static int ptyc_create_loop_thread( + nt_thread_params * params, + struct ptyc_driver_ctx_impl * ictx, + nt_thread_start_routine * entry) +{ + struct ptyc_loop_thread_ctx xctx; + + xctx.entry = entry; + xctx.ictx = ictx; + + /* rapunzel rapunzel */ + params->hprocess = NT_CURRENT_PROCESS_HANDLE; + params->start = ptyc_loop_thread_entry; + params->ext_ctx = &xctx; + params->ext_ctx_size = sizeof(xctx); + params->stack_size_commit = 64 * 1024; + params->stack_size_reserve = 64 * 1024; + params->creation_flags = NT_CREATE_LOCAL_THREAD; + + return ntapi->tt_create_thread( + params); +} + +static int ptyc_free_console_impl( + struct ptyc_driver_ctx_impl * ictx, + int32_t status) +{ + struct ptyc_term_ctx * tctx; + struct ptyc_loop_ctx * lctx; + + tctx = &ictx->tctx; + lctx = &ictx->lctx; + + if (tctx->hin) + ntcon->free_console(); + + if (lctx->treader.hthread) + ntapi->zw_close(lctx->treader.hthread); + + if (lctx->twriter.hthread) + ntapi->zw_close(lctx->twriter.hthread); + + if (lctx->tpoller.hthread) + ntapi->zw_close(lctx->tpoller.hthread); + + if (lctx->tdbgevent.hthread) + ntapi->zw_close(lctx->tdbgevent.hthread); + + if (lctx->tdbgoven.hthread) + ntapi->zw_close(lctx->tdbgoven.hthread); + + if (lctx->tdbgraw.hthread) + ntapi->zw_close(lctx->tdbgraw.hthread); + + return status; +} + +static int ptyc_init_console(struct ptyc_term_ctx * tctx) +{ + /* console input buffer) */ + if (!(tctx->hin = ntcon->get_std_handle(NT_STD_INPUT_HANDLE))) + return NT_STATUS_UNSUCCESSFUL; + + /* console screen buffer */ + if (!(tctx->hout = ntcon->create_console_screen_buffer( + NT_GENERIC_READ | NT_GENERIC_WRITE, + 0,0,NT_CONSOLE_TEXTMODE_BUFFER,0))) + return NT_STATUS_UNSUCCESSFUL; + + if (!(ntcon->set_console_active_screen_buffer(tctx->hout))) + return NT_STATUS_UNSUCCESSFUL; + + /* console text attributes: default colors */ + if (!(ntcon->set_console_text_attribute( + tctx->hout, + NT_BACKGROUND_BLACK | NT_FOREGROUND_WHITE))) + return NT_STATUS_UNSUCCESSFUL; + + /* console code page: utf-8 */ + if (!(ntcon->set_console_code_page(65001))) + return NT_STATUS_NOT_SUPPORTED; + + if (!(ntcon->set_console_output_code_page(65001))) + return NT_STATUS_NOT_SUPPORTED; + + /* input events */ + if (!(ntcon->set_console_mode( + tctx->hin, + NT_ENABLE_MOUSE_INPUT + | NT_ENABLE_WINDOW_INPUT))) + return NT_STATUS_UNSUCCESSFUL; + + /* ctrl events */ + if (!(ntcon->set_console_ctrl_handler( + ptyc_console_ctrl, + true))) + return NT_STATUS_UNSUCCESSFUL; + + return NT_STATUS_SUCCESS; +} + +int ptyc_alloc_console(struct ptyc_driver_ctx * dctx) +{ + int32_t status; + struct ptyc_driver_ctx_impl * ictx; + struct ptyc_term_ctx * tctx; + struct ptyc_loop_ctx * lctx; + + if (!(ictx = ptyc_get_driver_ictx(dctx))) + return NT_STATUS_INVALID_HANDLE; + + tctx = &ictx->tctx; + lctx = &ictx->lctx; + + if (!(ntcon->alloc_console())) + return NT_STATUS_UNSUCCESSFUL; + + if ((status = ptyc_init_console(tctx))) + return ptyc_set_status(dctx,status); + + if ((status = ptyc_create_loop_thread( + &lctx->treader, + ictx,ptyc_console_reader))) + return ptyc_set_status(dctx,status); + + if ((status = ptyc_create_loop_thread( + &lctx->twriter, + ictx,ptyc_console_writer))) + return ptyc_set_status(dctx,status); + + if ((status = ptyc_create_loop_thread( + &lctx->tpoller, + ictx,ptyc_console_poller))) + return ptyc_set_status(dctx,status); + + if (dctx->cctx->drvflags & PTYC_DRIVER_DBG_EVENT) + if ((status = ptyc_create_loop_thread( + &lctx->tdbgevent, + ictx,ptyc_dbg_event))) + return ptyc_set_status(dctx,status); + + if (dctx->cctx->drvflags & PTYC_DRIVER_DBG_OVEN) + if ((status = ptyc_create_loop_thread( + &lctx->tdbgoven, + ictx,ptyc_dbg_oven))) + return ptyc_set_status(dctx,status); + + if (dctx->cctx->drvflags & PTYC_DRIVER_DBG_RAW) + if ((status = ptyc_create_loop_thread( + &lctx->tdbgraw, + ictx,ptyc_dbg_raw))) + return ptyc_set_status(dctx,status); + + return ptyc_set_status(dctx,NT_STATUS_SUCCESS); +} + + +int ptyc_wait_for_console(struct ptyc_driver_ctx * dctx) +{ + struct ptyc_driver_ctx_impl * ictx; + + if (!(ictx = ptyc_get_driver_ictx(dctx))) + return NT_STATUS_INVALID_HANDLE; + + return ntapi->zw_wait_for_single_object( + ictx->lctx.tpoller.hthread, + NT_SYNC_ALERTABLE,0); +} + + +void ptyc_free_console(struct ptyc_driver_ctx * dctx) +{ + struct ptyc_driver_ctx_impl * ictx; + + if (!(ictx = ptyc_get_driver_ictx(dctx))) + return; + + ptyc_free_console_impl(ictx,NT_STATUS_SUCCESS); +} diff --git a/src/console/ptyc_console_ctrl.c b/src/console/ptyc_console_ctrl.c new file mode 100644 index 0000000..d20ef12 --- /dev/null +++ b/src/console/ptyc_console_ctrl.c @@ -0,0 +1,18 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_console_ctrl(uint32_t type) +{ + return type; +} diff --git a/src/console/ptyc_console_poller.c b/src/console/ptyc_console_poller.c new file mode 100644 index 0000000..60e3d8b --- /dev/null +++ b/src/console/ptyc_console_poller.c @@ -0,0 +1,19 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_console_poller(struct ptyc_driver_ctx_impl * ictx) +{ + (void)ictx; + return ntapi->tt_wait_for_dummy_event(); +} diff --git a/src/console/ptyc_console_reader.c b/src/console/ptyc_console_reader.c new file mode 100644 index 0000000..3afab13 --- /dev/null +++ b/src/console/ptyc_console_reader.c @@ -0,0 +1,19 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_console_reader(struct ptyc_driver_ctx_impl * ictx) +{ + (void)ictx; + return ntapi->tt_wait_for_dummy_event(); +} diff --git a/src/console/ptyc_console_writer.c b/src/console/ptyc_console_writer.c new file mode 100644 index 0000000..a0ea461 --- /dev/null +++ b/src/console/ptyc_console_writer.c @@ -0,0 +1,19 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_console_writer(struct ptyc_driver_ctx_impl * ictx) +{ + (void)ictx; + return ntapi->tt_wait_for_dummy_event(); +} diff --git a/src/debug/ptyc_dbg_event.c b/src/debug/ptyc_dbg_event.c new file mode 100644 index 0000000..45cea3e --- /dev/null +++ b/src/debug/ptyc_dbg_event.c @@ -0,0 +1,19 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_dbg_event(struct ptyc_driver_ctx_impl * ictx) +{ + (void)ictx; + return ntapi->tt_wait_for_dummy_event(); +} diff --git a/src/debug/ptyc_dbg_oven.c b/src/debug/ptyc_dbg_oven.c new file mode 100644 index 0000000..393076d --- /dev/null +++ b/src/debug/ptyc_dbg_oven.c @@ -0,0 +1,19 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_dbg_oven(struct ptyc_driver_ctx_impl * ictx) +{ + (void)ictx; + return ntapi->tt_wait_for_dummy_event(); +} diff --git a/src/debug/ptyc_dbg_raw.c b/src/debug/ptyc_dbg_raw.c new file mode 100644 index 0000000..8804ca6 --- /dev/null +++ b/src/debug/ptyc_dbg_raw.c @@ -0,0 +1,19 @@ +/*********************************************************/ +/* ptycon: a pty-console bridge */ +/* Copyright (C) 2016 Z. Gilboa */ +/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */ +/*********************************************************/ + +#include +#include +#include +#include + +#include +#include "ptycon_driver_impl.h" + +int ptyc_dbg_raw(struct ptyc_driver_ctx_impl * ictx) +{ + (void)ictx; + return ntapi->tt_wait_for_dummy_event(); +} diff --git a/src/driver/ptyc_amain.c b/src/driver/ptyc_amain.c index 3a5ca68..f94b236 100644 --- a/src/driver/ptyc_amain.c +++ b/src/driver/ptyc_amain.c @@ -73,5 +73,11 @@ int ptyc_main(int argc, char ** argv, char ** envp) if (ptyc_alloc_pty(dctx)) return ptyc_exit(dctx,2); + if (ptyc_alloc_console(dctx)) + return ptyc_exit(dctx,2); + + if (ptyc_wait_for_console(dctx)) + return ptyc_exit(dctx,2); + return ptyc_exit(dctx,ret); } diff --git a/src/internal/ptycon_driver_impl.h b/src/internal/ptycon_driver_impl.h index c46e146..86336c5 100644 --- a/src/internal/ptycon_driver_impl.h +++ b/src/internal/ptycon_driver_impl.h @@ -26,7 +26,25 @@ enum app_tags { TAG_DEBUG, }; +struct ptyc_term_ctx { + void * hin; + void * hout; +}; + +struct ptyc_loop_ctx { + nt_thread_params treader; + nt_thread_params twriter; + nt_thread_params tpoller; + nt_thread_params tdbgevent; + nt_thread_params tdbgoven; + nt_thread_params tdbgraw; + int32_t ficonic; + int32_t fwinsize; +}; + struct ptyc_driver_ctx_impl { + struct ptyc_term_ctx tctx; + struct ptyc_loop_ctx lctx; struct ptyc_common_ctx cctx; struct ptyc_driver_ctx ctx; };