| |
| |
| |
| |
| |
| |
| #include <psxtypes/psxtypes.h> |
| #include <ntcon/ntcon.h> |
| #include <ntapi/ntapi.h> |
| #include <gdi/gdi.h> |
| |
| #include <ptycon/ptycon.h> |
| #include "ptycon_driver_impl.h" |
| #include "ptycon_status_impl.h" |
| |
| int __stdcall ptyc_console_ctrl(uint32_t); |
| |
| int __stdcall ptyc_console_reader(void *); |
| int __stdcall ptyc_console_writer(void *);; |
| int __stdcall ptyc_console_poller(void *); |
| |
| int __stdcall ptyc_dbg_cat(struct ptyc_driver_ctx *); |
| int __stdcall ptyc_dbg_event(void *); |
| int __stdcall ptyc_dbg_oven(void *); |
| int __stdcall ptyc_dbg_raw(void *); |
| |
| |
| struct ptyc_loop_thread_ctx { |
| nt_thread_start_routine * entry; |
| struct ptyc_driver_ctx_impl * ictx; |
| }; |
| |
| static int __stdcall 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; |
| |
| |
| 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) |
| { |
| |
| if (!(tctx->hin = ntcon->get_std_handle(NT_STD_INPUT_HANDLE))) |
| return NT_STATUS_UNSUCCESSFUL; |
| |
| |
| 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_screen_buffer_size( |
| tctx->hout, |
| tctx->screen_size))) |
| return NT_STATUS_UNSUCCESSFUL; |
| |
| if (!(ntcon->set_console_active_screen_buffer(tctx->hout))) |
| return NT_STATUS_UNSUCCESSFUL; |
| |
| |
| if (!(ntcon->set_console_text_attribute( |
| tctx->hout, |
| NT_BACKGROUND_BLACK | NT_FOREGROUND_WHITE))) |
| return NT_STATUS_UNSUCCESSFUL; |
| |
| |
| 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; |
| |
| |
| if (!(ntcon->set_console_mode( |
| tctx->hin, |
| NT_ENABLE_MOUSE_INPUT |
| | NT_ENABLE_WINDOW_INPUT))) |
| return NT_STATUS_UNSUCCESSFUL; |
| |
| |
| if (!(ntcon->set_console_ctrl_handler( |
| ptyc_console_ctrl, |
| true))) |
| return NT_STATUS_UNSUCCESSFUL; |
| |
| |
| if (!(ntcon->get_console_cursor_info( |
| tctx->hout, |
| &tctx->cursor_info))) |
| 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; |
| |
| tctx->screen_size.x = 512; |
| tctx->screen_size.y = 4096; |
| tctx->drvflags = ictx->cctx.drvflags; |
| |
| 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); |
| |
| if ((status = ptyc_dbg_cat(dctx))) |
| 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); |
| } |