/*********************************************************/
/* ptycon: a pty-console bridge */
/* Copyright (C) 2016--2017 SysDeer Technologies, LLC */
/* Released under GPLv2 and GPLv3; see COPYING.PTYCON. */
/*********************************************************/
#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"
int __stdcall ptyc_console_poller(struct ptyc_driver_ctx_impl * ictx)
{
int32_t status;
int32_t iostatus;
struct ptyc_term_ctx * tctx;
struct ptyc_driver_ctx * dctx;
nt_tty_sigctl_info ctlinfo;
void * hwnd;
void * hevent;
nt_timeout timeout;
nt_iosb iosb;
gdi_rect orect;
gdi_rect crect;
int diff;
tctx = &ictx->tctx;
dctx = &ictx->ctx;
if (!(hwnd = ntcon->get_console_window()))
return NT_STATUS_INTERNAL_ERROR;
if ((status = ntapi->tt_create_private_event(
&hevent,
NT_NOTIFICATION_EVENT,
NT_EVENT_NOT_SIGNALED)))
return status;
if (!(gdi->get_client_rect(
hwnd,
&orect)))
return NT_STATUS_INTERNAL_ERROR;
timeout.quad = (-1) * 10 * 1000 * 50;
do {
status = ntapi->zw_wait_for_single_object(
hevent,
NT_SYNC_ALERTABLE,
&timeout);
if (!(gdi->get_client_rect(
hwnd,
&crect)))
return NT_STATUS_INTERNAL_ERROR;
diff = (crect.right-crect.left !=orect.right-orect.left)
|| (crect.bottom-crect.top !=orect.bottom-orect.top);
if (diff) {
orect.left = crect.left;
orect.right = crect.right;
orect.top = crect.top;
orect.bottom = crect.bottom;
if (!(ntcon->get_console_screen_buffer_info(
tctx->hout,
&tctx->screen_info)))
return NT_STATUS_INTERNAL_ERROR;
ntapi->tt_aligned_block_memset(
&ctlinfo,0,sizeof(ctlinfo));
ctlinfo.winsize.ws_col = tctx->screen_info.window.right
- tctx->screen_info.window.left
+ 1;
ctlinfo.winsize.ws_row = tctx->screen_info.window.bottom
- tctx->screen_info.window.top
+ 1;
if ((iostatus = ntapi->pty_ioctl(
ictx->cctx.hptm,
0,0,0,
&iosb,
TTY_TIOCSWINSZ,
&ctlinfo,sizeof(ctlinfo),
&ctlinfo,sizeof(ctlinfo))))
return iostatus;
}
} while ((status == NT_STATUS_TIMEOUT) && (dctx->status == NT_STATUS_SUCCESS));
return (dctx->status == NT_STATUS_PIPE_DISCONNECTED)
? NT_STATUS_SUCCESS
: dctx->status ? dctx->status : status;
}