#include <curses.priv.h>
#define CUR my_term.type.
-MODULE_ID("$Id: win_driver.c,v 1.31 2014/04/13 00:16:07 tom Exp $")
+MODULE_ID("$Id: win_driver.c,v 1.33 2014/04/26 19:32:05 juergen Exp $")
#define WINMAGIC NCDRV_MAGIC(NCDRV_WINCONSOLE)
#define FKEYS 24
#define MAPSIZE (FKEYS + N_INI)
#define NUMPAIRS 64
+#define HANDLE_CAST(f) (HANDLE)(intptr_t)(f)
typedef struct props {
CONSOLE_SCREEN_BUFFER_INFO SBI;
#define PropOf(TCB) ((Properties*)TCB->prop)
+#if WINVER >= 0x0600
+/* This function tests, whether or not the ncurses application
+ is running as a descendant of MSYS2/cygwin mintty terminal
+ application. mintty doesn't use Windows Console for it's screen
+ I/O, so the native Windows _isatty doesn't recognize it as
+ character device. But we can discover we are at the end of an
+ Pipe and can query to server side of the pipe, looking whether
+ or not this is mintty.
+ */
+static int
+_ismintty(int fd, LPHANDLE pMinTTY)
+{
+ HANDLE handle;
+ DWORD dw;
+
+ handle = HANDLE_CAST(_get_osfhandle(fd));
+ if (handle == INVALID_HANDLE_VALUE)
+ return 0;
+
+ dw = GetFileType(handle);
+ if (dw == FILE_TYPE_PIPE) {
+ if (GetNamedPipeInfo(handle, 0, 0, 0, 0)) {
+ ULONG pPid;
+ /* Requires NT6 */
+ if (GetNamedPipeServerProcessId(handle, &pPid)) {
+ TCHAR buf[MAX_PATH];
+ DWORD len = 0;
+ /* These security attributes may allow us to
+ create a remote thread in mintty to manipulate
+ the terminal state remotely */
+ HANDLE pHandle = OpenProcess(PROCESS_CREATE_THREAD
+ | PROCESS_QUERY_INFORMATION
+ | PROCESS_VM_OPERATION
+ | PROCESS_VM_WRITE
+ | PROCESS_VM_READ,
+ FALSE,
+ pPid);
+ if (pMinTTY)
+ *pMinTTY = INVALID_HANDLE_VALUE;
+ if (pHandle == INVALID_HANDLE_VALUE)
+ return 0;
+ if (len = GetProcessImageFileName(pHandle,
+ buf,
+ (DWORD) (sizeof(buf) /
+ sizeof(*buf)))) {
+ TCHAR *pos = _tcsrchr(buf, _T('\\'));
+ if (pos) {
+ pos++;
+ if (_tcsnicmp(pos, _TEXT("mintty.exe"), 10) == 0) {
+ if (pMinTTY)
+ *pMinTTY = pHandle;
+ return 1;
+ }
+ }
+ }
+ }
+ }
+ }
+ return 0;
+}
+#endif
+
+/* Our replacement for the systems _isatty to include also
+ a test for mintty. This is called from the NC_ISATTY macro
+ defined in curses.priv.h
+ */
+int
+_nc_mingw_isatty(int fd)
+{
+ if (_isatty(fd))
+ return 1;
+#if WINVER < 0x0600
+ return 0;
+#else
+ return _ismintty(fd, NULL);
+#endif
+}
+
+/* Borrowed from ansicon project.
+ Check whether or not a I/O handle is associated with
+ a Windows console.
+*/
+static BOOL
+IsConsoleHandle(HANDLE hdl)
+{
+ DWORD dwFlag = 0;
+ if (!GetConsoleMode(hdl, &dwFlag)) {
+ return (int) WriteConsoleA(hdl, NULL, 0, &dwFlag, NULL);
+ }
+ return (int) (dwFlag & ENABLE_PROCESSED_OUTPUT);
+}
+
+/* This is used when running in terminfo mode to discover,
+ whether or not the "terminal" is actually a Windows
+ Console. It's the responsibilty of the console to deal
+ with the terminal escape sequences that are sent by
+ terminfo.
+ */
+int
+_nc_mingw_isconsole(int fd)
+{
+ HANDLE hdl = HANDLE_CAST(_get_osfhandle(fd));
+ return (int) IsConsoleHandle(hdl);
+}
+
int
_nc_mingw_ioctl(int fd GCC_UNUSED,
long int request GCC_UNUSED,
}
static const char *
-drv_name(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_name(TERMINAL_CONTROL_BLOCK * TCB)
{
(void) TCB;
return "win32console";
}
static int
-drv_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_doupdate(TERMINAL_CONTROL_BLOCK * TCB)
{
int result = ERR;
int y, nonempty, n, x0, x1, Width, Height;
AssertTCB();
SetSP();
- T((T_CALLED("win32con::drv_doupdate(%p)"), TCB));
+ T((T_CALLED("win32con::wcon_doupdate(%p)"), TCB));
if (okConsoleHandle(TCB)) {
Width = screen_columns(sp);
}
static bool
-drv_CanHandle(TERMINAL_CONTROL_BLOCK * TCB,
- const char *tname,
- int *errret GCC_UNUSED)
+wcon_CanHandle(TERMINAL_CONTROL_BLOCK * TCB,
+ const char *tname,
+ int *errret GCC_UNUSED)
{
bool code = FALSE;
- T((T_CALLED("win32con::drv_CanHandle(%p)"), TCB));
+ T((T_CALLED("win32con::wcon_CanHandle(%p)"), TCB));
assert((TCB != 0) && (tname != 0));
}
static int
-drv_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB,
- int beepFlag GCC_UNUSED)
+wcon_dobeepflash(TERMINAL_CONTROL_BLOCK * TCB,
+ int beepFlag GCC_UNUSED)
{
SCREEN *sp;
int res = ERR;
}
static int
-drv_print(TERMINAL_CONTROL_BLOCK * TCB,
- char *data GCC_UNUSED,
- int len GCC_UNUSED)
+wcon_print(TERMINAL_CONTROL_BLOCK * TCB,
+ char *data GCC_UNUSED,
+ int len GCC_UNUSED)
{
SCREEN *sp;
}
static int
-drv_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB,
- int fg GCC_UNUSED,
- int bg GCC_UNUSED)
+wcon_defaultcolors(TERMINAL_CONTROL_BLOCK * TCB,
+ int fg GCC_UNUSED,
+ int bg GCC_UNUSED)
{
SCREEN *sp;
int code = ERR;
}
static void
-drv_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
- int fore,
- int color,
- int (*outc) (SCREEN *, int) GCC_UNUSED)
+wcon_setcolor(TERMINAL_CONTROL_BLOCK * TCB,
+ int fore,
+ int color,
+ int (*outc) (SCREEN *, int) GCC_UNUSED)
{
AssertTCB();
}
static bool
-drv_rescol(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_rescol(TERMINAL_CONTROL_BLOCK * TCB)
{
bool res = FALSE;
}
static bool
-drv_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_rescolors(TERMINAL_CONTROL_BLOCK * TCB)
{
int result = FALSE;
SCREEN *sp;
}
static int
-drv_size(TERMINAL_CONTROL_BLOCK * TCB, int *Lines, int *Cols)
+wcon_size(TERMINAL_CONTROL_BLOCK * TCB, int *Lines, int *Cols)
{
int result = ERR;
AssertTCB();
- T((T_CALLED("win32con::drv_size(%p)"), TCB));
+ T((T_CALLED("win32con::wcon_size(%p)"), TCB));
if (okConsoleHandle(TCB) &&
PropOf(TCB) != 0 &&
}
static int
-drv_setsize(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED,
- int l GCC_UNUSED,
- int c GCC_UNUSED)
+wcon_setsize(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED,
+ int l GCC_UNUSED,
+ int c GCC_UNUSED)
{
AssertTCB();
return ERR;
}
static int
-drv_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf)
+wcon_sgmode(TERMINAL_CONTROL_BLOCK * TCB, int setFlag, TTY * buf)
{
DWORD dwFlag = 0;
tcflag_t iflag;
}
static int
-drv_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
+wcon_mode(TERMINAL_CONTROL_BLOCK * TCB, int progFlag, int defFlag)
{
SCREEN *sp;
TERMINAL *_term = (TERMINAL *) TCB;
AssertTCB();
sp = TCB->csp;
- T((T_CALLED("win32con::drv_mode(%p, prog=%d, def=%d)"), TCB, progFlag, defFlag));
+ T((T_CALLED("win32con::wcon_mode(%p, prog=%d, def=%d)"), TCB, progFlag, defFlag));
PropOf(TCB)->progMode = progFlag;
PropOf(TCB)->lastOut = progFlag ? TCB->hdl : TCB->out;
SetConsoleActiveScreenBuffer(PropOf(TCB)->lastOut);
if (progFlag) /* prog mode */ {
if (defFlag) {
- if ((drv_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
+ if ((wcon_sgmode(TCB, FALSE, &(_term->Nttyb)) == OK)) {
_term->Nttyb.c_oflag &= (tcflag_t) (~OFLAGS_TABS);
code = OK;
}
} else {
/* reset_prog_mode */
- if (drv_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
+ if (wcon_sgmode(TCB, TRUE, &(_term->Nttyb)) == OK) {
if (sp) {
if (sp->_keypad_on)
_nc_keypad(sp, TRUE);
} else { /* shell mode */
if (defFlag) {
/* def_shell_mode */
- if (drv_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
+ if (wcon_sgmode(TCB, FALSE, &(_term->Ottyb)) == OK) {
code = OK;
}
} else {
_nc_keypad(sp, FALSE);
NCURSES_SP_NAME(_nc_flush) (sp);
}
- code = drv_sgmode(TCB, TRUE, &(_term->Ottyb));
+ code = wcon_sgmode(TCB, TRUE, &(_term->Ottyb));
if (!PropOf(TCB)->buffered) {
if (!restore_original_screen(TCB))
code = ERR;
}
static void
-drv_screen_init(SCREEN *sp GCC_UNUSED)
+wcon_screen_init(SCREEN *sp GCC_UNUSED)
{
}
static void
-drv_wrap(SCREEN *sp GCC_UNUSED)
+wcon_wrap(SCREEN *sp GCC_UNUSED)
{
}
}
static void
-drv_release(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_release(TERMINAL_CONTROL_BLOCK * TCB)
{
- T((T_CALLED("win32con::drv_release(%p)"), TCB));
+ T((T_CALLED("win32con::wcon_release(%p)"), TCB));
AssertTCB();
if (TCB->prop)
}
static void
-drv_init(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_init(TERMINAL_CONTROL_BLOCK * TCB)
{
DWORD num_buttons;
- T((T_CALLED("win32con::drv_init(%p)"), TCB));
+ T((T_CALLED("win32con::wcon_init(%p)"), TCB));
AssertTCB();
PropOf(TCB)->buffered = buffered;
PropOf(TCB)->window_only = FALSE;
if (!get_SBI(TCB)) {
- FreeAndNull(TCB->prop); /* force error in drv_size */
+ FreeAndNull(TCB->prop); /* force error in wcon_size */
returnVoid;
}
if (!buffered) {
if (!save_original_screen(TCB)) {
- FreeAndNull(TCB->prop); /* force error in drv_size */
+ FreeAndNull(TCB->prop); /* force error in wcon_size */
returnVoid;
}
}
}
static void
-drv_initpair(TERMINAL_CONTROL_BLOCK * TCB,
- int pair,
- int f,
- int b)
+wcon_initpair(TERMINAL_CONTROL_BLOCK * TCB,
+ int pair,
+ int f,
+ int b)
{
SCREEN *sp;
}
static void
-drv_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
- int color GCC_UNUSED,
- int r GCC_UNUSED,
- int g GCC_UNUSED,
- int b GCC_UNUSED)
+wcon_initcolor(TERMINAL_CONTROL_BLOCK * TCB,
+ int color GCC_UNUSED,
+ int r GCC_UNUSED,
+ int g GCC_UNUSED,
+ int b GCC_UNUSED)
{
SCREEN *sp;
}
static void
-drv_do_color(TERMINAL_CONTROL_BLOCK * TCB,
- int old_pair GCC_UNUSED,
- int pair GCC_UNUSED,
- int reverse GCC_UNUSED,
- int (*outc) (SCREEN *, int) GCC_UNUSED
+wcon_do_color(TERMINAL_CONTROL_BLOCK * TCB,
+ int old_pair GCC_UNUSED,
+ int pair GCC_UNUSED,
+ int reverse GCC_UNUSED,
+ int (*outc) (SCREEN *, int) GCC_UNUSED
)
{
SCREEN *sp;
}
static void
-drv_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_initmouse(TERMINAL_CONTROL_BLOCK * TCB)
{
SCREEN *sp;
}
static int
-drv_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay)
+wcon_testmouse(TERMINAL_CONTROL_BLOCK * TCB, int delay)
{
int rc = 0;
SCREEN *sp;
}
static int
-drv_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
- int yold GCC_UNUSED, int xold GCC_UNUSED,
- int y, int x)
+wcon_mvcur(TERMINAL_CONTROL_BLOCK * TCB,
+ int yold GCC_UNUSED, int xold GCC_UNUSED,
+ int y, int x)
{
int ret = ERR;
if (okConsoleHandle(TCB)) {
}
static void
-drv_hwlabel(TERMINAL_CONTROL_BLOCK * TCB,
- int labnum GCC_UNUSED,
- char *text GCC_UNUSED)
+wcon_hwlabel(TERMINAL_CONTROL_BLOCK * TCB,
+ int labnum GCC_UNUSED,
+ char *text GCC_UNUSED)
{
SCREEN *sp;
}
static void
-drv_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB,
- int OnFlag GCC_UNUSED)
+wcon_hwlabelOnOff(TERMINAL_CONTROL_BLOCK * TCB,
+ int OnFlag GCC_UNUSED)
{
SCREEN *sp;
}
static chtype
-drv_conattr(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
+wcon_conattr(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED)
{
chtype res = A_NORMAL;
res |= (A_BOLD | A_DIM | A_REVERSE | A_STANDOUT | A_COLOR);
}
static void
-drv_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
+wcon_setfilter(TERMINAL_CONTROL_BLOCK * TCB)
{
SCREEN *sp;
}
static void
-drv_initacs(TERMINAL_CONTROL_BLOCK * TCB,
- chtype *real_map GCC_UNUSED,
- chtype *fake_map GCC_UNUSED)
+wcon_initacs(TERMINAL_CONTROL_BLOCK * TCB,
+ chtype *real_map GCC_UNUSED,
+ chtype *fake_map GCC_UNUSED)
{
#define DATA(a,b) { a, b }
static struct {
}
static int
-drv_twait(TERMINAL_CONTROL_BLOCK * TCB,
- int mode,
- int milliseconds,
- int *timeleft
- EVENTLIST_2nd(_nc_eventlist * evl))
+wcon_twait(TERMINAL_CONTROL_BLOCK * TCB,
+ int mode,
+ int milliseconds,
+ int *timeleft
+ EVENTLIST_2nd(_nc_eventlist * evl))
{
SCREEN *sp;
INPUT_RECORD inp_rec;
}
static int
-drv_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
+wcon_read(TERMINAL_CONTROL_BLOCK * TCB, int *buf)
{
SCREEN *sp;
int n = 1;
memset(&inp_rec, 0, sizeof(inp_rec));
- T((T_CALLED("win32con::drv_read(%p)"), TCB));
+ T((T_CALLED("win32con::wcon_read(%p)"), TCB));
while ((b = ReadConsoleInput(TCB->inp, &inp_rec, 1, &nRead))) {
if (b && nRead > 0) {
if (inp_rec.EventType == KEY_EVENT) {
}
static int
-drv_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms)
+wcon_nap(TERMINAL_CONTROL_BLOCK * TCB GCC_UNUSED, int ms)
{
- T((T_CALLED("win32con::drv_nap(%p, %d)"), TCB, ms));
+ T((T_CALLED("win32con::wcon_nap(%p, %d)"), TCB, ms));
Sleep((DWORD) ms);
returnCode(OK);
}
static bool
-drv_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int keycode)
+wcon_kyExist(TERMINAL_CONTROL_BLOCK * TCB, int keycode)
{
SCREEN *sp;
WORD nKey;
AssertTCB();
- T((T_CALLED("win32con::drv_kyExist(%p, %d)"), TCB, keycode));
+ T((T_CALLED("win32con::wcon_kyExist(%p, %d)"), TCB, keycode));
res = bsearch(&key,
PropOf(TCB)->rmap,
(size_t) (N_INI + FKEYS),
}
static int
-drv_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag GCC_UNUSED)
+wcon_kpad(TERMINAL_CONTROL_BLOCK * TCB, int flag GCC_UNUSED)
{
SCREEN *sp;
int code = ERR;
AssertTCB();
sp = TCB->csp;
- T((T_CALLED("win32con::drv_kpad(%p, %d)"), TCB, flag));
+ T((T_CALLED("win32con::wcon_kpad(%p, %d)"), TCB, flag));
if (sp) {
code = OK;
}
}
static int
-drv_keyok(TERMINAL_CONTROL_BLOCK * TCB, int keycode, int flag)
+wcon_keyok(TERMINAL_CONTROL_BLOCK * TCB, int keycode, int flag)
{
int code = ERR;
SCREEN *sp;
AssertTCB();
SetSP();
- T((T_CALLED("win32con::drv_keyok(%p, %d, %d)"), TCB, keycode, flag));
+ T((T_CALLED("win32con::wcon_keyok(%p, %d, %d)"), TCB, keycode, flag));
if (sp) {
res = bsearch(&key,
PropOf(TCB)->rmap,
NCURSES_EXPORT_VAR (TERM_DRIVER) _nc_WIN_DRIVER = {
FALSE,
- drv_name, /* Name */
- drv_CanHandle, /* CanHandle */
- drv_init, /* init */
- drv_release, /* release */
- drv_size, /* size */
- drv_sgmode, /* sgmode */
- drv_conattr, /* conattr */
- drv_mvcur, /* hwcur */
- drv_mode, /* mode */
- drv_rescol, /* rescol */
- drv_rescolors, /* rescolors */
- drv_setcolor, /* color */
- drv_dobeepflash, /* DoBeepFlash */
- drv_initpair, /* initpair */
- drv_initcolor, /* initcolor */
- drv_do_color, /* docolor */
- drv_initmouse, /* initmouse */
- drv_testmouse, /* testmouse */
- drv_setfilter, /* setfilter */
- drv_hwlabel, /* hwlabel */
- drv_hwlabelOnOff, /* hwlabelOnOff */
- drv_doupdate, /* update */
- drv_defaultcolors, /* defaultcolors */
- drv_print, /* print */
- drv_size, /* getsize */
- drv_setsize, /* setsize */
- drv_initacs, /* initacs */
- drv_screen_init, /* scinit */
- drv_wrap, /* scexit */
- drv_twait, /* twait */
- drv_read, /* read */
- drv_nap, /* nap */
- drv_kpad, /* kpad */
- drv_keyok, /* kyOk */
- drv_kyExist /* kyExist */
+ wcon_name, /* Name */
+ wcon_CanHandle, /* CanHandle */
+ wcon_init, /* init */
+ wcon_release, /* release */
+ wcon_size, /* size */
+ wcon_sgmode, /* sgmode */
+ wcon_conattr, /* conattr */
+ wcon_mvcur, /* hwcur */
+ wcon_mode, /* mode */
+ wcon_rescol, /* rescol */
+ wcon_rescolors, /* rescolors */
+ wcon_setcolor, /* color */
+ wcon_dobeepflash, /* DoBeepFlash */
+ wcon_initpair, /* initpair */
+ wcon_initcolor, /* initcolor */
+ wcon_do_color, /* docolor */
+ wcon_initmouse, /* initmouse */
+ wcon_testmouse, /* testmouse */
+ wcon_setfilter, /* setfilter */
+ wcon_hwlabel, /* hwlabel */
+ wcon_hwlabelOnOff, /* hwlabelOnOff */
+ wcon_doupdate, /* update */
+ wcon_defaultcolors, /* defaultcolors */
+ wcon_print, /* print */
+ wcon_size, /* getsize */
+ wcon_setsize, /* setsize */
+ wcon_initacs, /* initacs */
+ wcon_screen_init, /* scinit */
+ wcon_wrap, /* scexit */
+ wcon_twait, /* twait */
+ wcon_read, /* read */
+ wcon_nap, /* nap */
+ wcon_kpad, /* kpad */
+ wcon_keyok, /* kyOk */
+ wcon_kyExist /* kyExist */
};