/*
 *  R : A Computer Language for Statistical Data Analysis
 *  file console.c
 *  Copyright (C) 1998--2003  Guido Masarotto and Brian Ripley
 *  Copyright (C) 2004-8      The R Foundation
 *  Copyright (C) 2004-2021   The R Core Team
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, a copy is available at
 *  https://www.R-project.org/Licenses/
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include "win-nls.h"
#include <R_ext/Boolean.h>
extern Rboolean mbcslocale;

#define USE_MDI 1
extern void R_ProcessEvents(void);
extern void R_WaitEvent(void);

#define WIN32_LEAN_AND_MEAN 1
#include <windows.h>
#include <string.h>
#include <ctype.h>
#include <wchar.h>
#include <limits.h>
#include <rlocale.h>
#include <R_ext/Memory.h>
#include "graphapp/ga.h"
#ifdef USE_MDI
#include "graphapp/stdimg.h"
#endif
#include "console.h"
#include "consolestructs.h"
#include "rui.h"
#include "getline/wc_history.h"
#include "Startup.h" /* for CharacterMode */
#include <Fileio.h>

#include <stdint.h>

/* Surrogate Pairs Macro */
#define SURROGATE_PAIRS_HI_MIN  ((uint16_t)0xd800)
#define SURROGATE_PAIRS_HI_MAX  ((uint16_t)0xdbff)
#define SURROGATE_PAIRS_LO_MIN  ((uint16_t)0xdc00)
#define SURROGATE_PAIRS_LO_MAX  ((uint16_t)0xdfff)
#define SURROGATE_PAIRS_BIT_SZ  ((uint32_t)10)
#define SURROGATE_PAIRS_MASK    (((uint16_t)1 << SURROGATE_PAIRS_BIT_SZ)-1)
#define IsSurrogatePairsHi(_h)  (SURROGATE_PAIRS_HI_MIN == \
		      ((uint16_t)(_h) &~ (uint16_t)SURROGATE_PAIRS_MASK ))
#define IsSurrogatePairsLo(_l)  (SURROGATE_PAIRS_LO_MIN == \
		      ((uint16_t)(_l) &~ (uint16_t)SURROGATE_PAIRS_MASK ))

#ifdef __GNUC__
# undef alloca
# define alloca(x) __builtin_alloca((x))
#endif

static void performCompletion(control c);


static inline int wcswidth(const wchar_t *s)
{
    return mbcslocale ? Ri18n_wcswidth(s, wcslen(s)) : wcslen(s);
}

static inline int wcwidth(const wchar_t s)
{
    return mbcslocale ? Ri18n_wcwidth(s) : 1;
}

static void setCURCOL(ConsoleData p)
{
    wchar_t *P = LINE(NUMLINES - 1);
    int w0 = 0;

    for (; P < LINE(NUMLINES - 1) + prompt_len + cur_pos; P++)
	if(*P == L'\r') w0 = 0; else w0 += wcwidth(*P);

    CURCOL = w0;
}


/* xbuf */

xbuf newxbuf(xlong dim, xint ms, xint shift)
{
    xbuf  p;

    p = (xbuf) malloc(sizeof(struct structXBUF));
    if (!p)
	return NULL;
    p->b = (wchar_t *) malloc((dim + 1) * sizeof(wchar_t));
    if (!p->b) {
	free(p);
	return NULL;
    }
    p->user = (int *) malloc(ms * sizeof(int));
    if (!p->user) {
	free(p->b);
	free(p);
	return NULL;
    }
    p->s = (wchar_t **) malloc(ms * sizeof(wchar_t *));
    if (!p->s) {
	free(p->b);
	free(p->user);
	free(p);
	return NULL;
    }
    p->ns = 1;
    p->ms = ms;
    p->shift = shift;
    p->dim = dim;
    p->av = dim;
    p->free = p->b;
    p->s[0] = p->b;
    p->user[0] = -1;
    *p->b = L'\0';
    return p;
}

/* reallocate increased buffer sizes and update pointers */
void xbufgrow(xbuf p, xlong dim, xint ms)
{
    if(dim > p->dim) {
	wchar_t *ret = (wchar_t *) realloc(p->b, (dim + 1)*sizeof(wchar_t));
	if(ret) {
	    int i, change;
	    change = ret - p->b;
	    p->b = ret;
	    p->av += change;
	    p->free += change;
	    for (i = 0; i < p->ns; i++)  p->s[i] += change;
	    p->dim = dim;
	}
    }
    if(ms > p->ms) {
	wchar_t **ret = (wchar_t **) realloc(p->s, ms * sizeof(wchar_t *));
	if(ret) {
	    int *ret2 = (int *) realloc(p->user, ms * sizeof(int));
	    if(ret2) {
		p->s = ret;
		p->user = ret2;
		p->ms = ms;
	    }
	}
    }
}

void xbufdel(xbuf p)
{
   if (!p) return;
   free(p->s);
   free(p->b);
   free(p->user);
   free(p);
}

static void xbufshift(xbuf p)
{
    xint  i;
    xlong mshift;
    wchar_t *new0;

    if (p->shift >= p->ns) {
	p->ns = 1;
	p->av = p->dim;
	p->free = p->b;
	p->s[0] = p->b;
	*p->b = L'\0';
	p->user[0] = -1;
	return;
    }
    new0 = p->s[p->shift];
    mshift = new0 - p->s[0];
    memmove(p->b, p->s[p->shift], (p->dim - mshift) * sizeof(wchar_t));
    memmove(p->user, &p->user[p->shift], (p->ms - p->shift) * sizeof(int));
    for (i = p->shift; i < p->ns; i++)
	p->s[i - p->shift] = p->s[i] - mshift;
    p->ns = p->ns - p->shift;
    p->free -= mshift;
    p->av += mshift;
}

static int xbufmakeroom(xbuf p, xlong size)
{
    if (size > p->dim) return 0;
    while ((p->av < size) || (p->ns == p->ms)) {
	/* PR#17851 lost-scrollbar/lost-history issue could be handled here.
	   Comment from Bill Dunlap: "One could change the p->av<size case to
	   discard only enough lines to make space for the new characters, but
	   I don't know if this extra complexity would be worthwhile." */
	xbufshift(p);
    }
    p->av -= size;
    return 1;
}

#define XPUTC(c) {xbufmakeroom(p,1); *p->free++=c;}

void xbufaddxc(xbuf p, wchar_t c)
{
    int   i;

    switch (c) {
    case L'\a':
	gabeep();
	break;
    case L'\b':
	if ((p->s[p->ns - 1])[0]) {
	    p->free--;
	    p->av++;
	}
	break;
    case L'\t':
	XPUTC(L' ');
	*p->free = '\0';
	/* Changed to  width in 2.7.0 */
	for (i = wcswidth(p->s[p->ns - 1]); (i % TABSIZE); i++) XPUTC(L' ');
	break;
    case L'\n':
	XPUTC(L'\0');
	p->s[p->ns] = p->free;
	p->user[p->ns++] = -1;
	break;
    default:
	XPUTC(c);
    }
    *p->free = L'\0';
}

void xbufaddxs(xbuf p, const wchar_t *s, int user)
{
    const wchar_t *ps;
    int   l;

    l = user ? (p->s[p->ns - 1])[0] : -1;
    for (ps = s; *ps; ps++) xbufaddxc(p, *ps);
    p->user[p->ns - 1] = l;
}

#define IN_CONSOLE
#include "rgui_UTF8.h"
extern size_t Rf_utf8towcs(wchar_t *wc, const char *s, size_t n);
static size_t enctowcs(wchar_t *wc, char *s, int n)
{
    size_t nc = 0;
    char *pb, *pe;
    if((pb = strchr(s, UTF8in[0])) && *(pb+1) == UTF8in[1] &&
       *(pb+2) == UTF8in[2]) {
	*pb = '\0';
	nc += mbstowcs(wc, s, n);
	*pb = UTF8in[0]; /* preserve input string, needed in consolewrites */
	pb += 3; pe = pb;
	while(*pe &&
	      !((pe = strchr(pe, UTF8out[0])) && *(pe+1) == UTF8out[1] &&
	      *(pe+2) == UTF8out[2])) pe++;
	if(!*pe) return nc; /* FIXME */;
	*pe = '\0';
	/* convert string starting at pb from UTF-8 */
	nc += Rf_utf8towcs(wc+nc, pb, (pe-pb));
	*pe = UTF8out[0]; /* preserve input string, needed in consolewrites */
	pe += 3;
	nc += enctowcs(wc+nc, pe, n-nc);
    } else nc = mbstowcs(wc, s, n);
    return nc;
}

static void xbufadds(xbuf p, const char *s, int user)
{
    int n = strlen(s) + 1; /* UCS-2 must be no more chars */
    if (n < 1000) {
	wchar_t tmp[n];
	enctowcs(tmp, (char *) s, n);
	xbufaddxs(p, tmp, user);
    } else {
	/* very long line */
	wchar_t *tmp = (wchar_t*) malloc(n * sizeof(wchar_t));
	enctowcs(tmp, (char *) s, n);
	xbufaddxs(p, tmp, user);
	free(tmp);
    }
}

static void xbuffixl(xbuf p)
{
    wchar_t *ps;

    if (!p->ns) return;
    ps = p->s[p->ns - 1];
    p->free = ps + wcslen(ps);
    p->av = p->dim - (p->free - p->b);
}


/* console */

rgb guiColors[numGuiColors] = {
	White, Black, gaRed, /* consolebg, consolefg, consoleuser, */
	White, Black, gaRed, /* pagerbg, pagerfg, pagerhighlight,  */
	White, Black, gaRed, /* dataeditbg, dataeditfg, dataedituser */
	White, Black         /* editorbg, editorfg                 */
};

extern int R_HistorySize;  /* from Defn.h */

ConsoleData
newconsoledata(font f, int rows, int cols, int bufbytes, int buflines,
	       rgb *guiColors, int kind, int buffered, int cursor_blink)
{
    ConsoleData p;

    initapp(0, 0);
    p = (ConsoleData) malloc(sizeof(struct structConsoleData));
    if (!p)
	return NULL;
    p->kind = kind;
    /* PR#14624 claimed this was needed, with no example */
    p->chbrk = p->modbrk = '\0';
    if (kind == CONSOLE) {
	p->lbuf = newxbuf(bufbytes, buflines, SLBUF);
	if (!p->lbuf) {
	    free(p);
	    return NULL;
	}
	p->kbuf = malloc(NKEYS * sizeof(wchar_t));
	if (!p->kbuf) {
	    xbufdel(p->lbuf);
	    free(p);
	    return NULL;
	}
    } else {
	p->lbuf = NULL;
	p->kbuf = NULL;
    }
    BM = NULL;
    p->rows = rows;
    p->cols = cols;
    for (int i=0; i<numGuiColors; i++)
	p->guiColors[i] = guiColors[i];
    p->f = f;
    FH = fontheight(f);
    FW = fontwidth(f);
    WIDTH = (COLS + 1) * FW;
    HEIGHT = (ROWS + 1) * FH + 1; /* +1 avoids size problems in MDI */
    FV = FC = 0;
    NEWFV = NEWFC = 0;
    p->firstkey = p->numkeys = 0;
    p->clp = NULL;
    CURROW = -1;
    p->overwrite = 0;
    p->needredraw = 0;
    p->wipe_completion = 0;
    p->my0 = p->my1 = -1;
    p->mx0 = 5;
    p->mx1 = 14;
    p->sel = 0;
    p->input = 0;
    p->lazyupdate = buffered;
    p->cursor_blink = cursor_blink;
    return (p);
}

static int col_to_pos(ConsoleData p, int x)
{
    if(mbcslocale) {
	int w0 = 0, cnt = 0;
	wchar_t *P = LINE(CURROW);
	for (; w0 < x && *P && P - LINE(CURROW) <= max_pos + prompt_len; ) {
	    w0 += Ri18n_wcwidth(*P++);
	    cnt++;
	}
	return(cnt - prompt_len);
    } else
	return(min(x - prompt_len, max_pos));
}

static int within_input(ConsoleData p, int mx, int my)
{
    return(my == CURROW && mx >= prompt_wid && col_to_pos(p, mx) < max_pos);
}

/* Intersect the mouse selection with the input region. If no overlap or !apply, do nothing*/
static int intersect_input(ConsoleData p, int apply)
{
    int my0 = p->my0, my1 = p->my1, mx0 = p->mx0, mx1 = p->mx1, temp;
    if (my0 > my1 || (my0 == my1 && mx0 > my1)) { /* put them in order */
	temp = my0;
	my0 = my1;
	my1 = temp;
	temp = mx0;
	mx0 = mx1;
	mx1 = temp;
    }

    if (my1 < CURROW || my0 > CURROW) return(0);
    if (my0 < CURROW) mx0 = 0;
    if (my1 > CURROW) mx1 = COLS;
    if (mx1 < CURCOL || col_to_pos(p, mx0) >= max_pos) return(0);
    mx0 = max(mx0, prompt_wid);
    while (col_to_pos(p, mx1) >= max_pos) mx1--;
    if (apply) {
	p->mx0 = mx0;
	p->mx1 = mx1;
	p->my0 = my0;
	p->my1 = my1;
    }
    return(1);
}

/* Here fch and lch are columns, and we have to cope with both MBCS
   and double-width chars. */

static void writelineHelper(ConsoleData p, int fch, int lch,
			    rgb fgr, rgb bgr, int j, int len, wchar_t *s)
{
    rect  r;

    /* This is right, since columns are of fixed size */
    r = rect(BORDERX + fch * FW, BORDERY + j * FH, (lch - fch + 1) * FW, FH);
    gfillrect(BM, bgr, r);

    if (len > FC+fch) {
	/* Some of the string is visible: */
	if(mbcslocale) {
	    int i, w0, nc;
	    wchar_t *P = s, *q;
	    Rboolean leftedge;

	    nc = (wcslen(s) + 1) * sizeof(wchar_t); /* overkill */
	    wchar_t *buff = (wchar_t*) R_alloc(nc, sizeof(wchar_t));
	    q = buff;
	    leftedge = FC && (fch == 0);
	    if(leftedge) fch++;
	    for (w0 = -FC; w0 < fch && *P; P++) /* should have enough ... */
		w0 += Ri18n_wcwidth(*P);
	    /* Now we have got to on or just after the left edge.
	       Possibly have a widechar hanging over.
	       If so, fill with blanks.
	    */
	    if(w0 > fch) for(i = 0; i < w0 - fch; i++) *q++ = L' ';

	    if (leftedge) *q++ = L'$';

	    while (w0 < lch) {
		if(!*P) break;
		w0 += Ri18n_wcwidth(*P);
		if(w0 > lch) break; /* char straddling the right edge
				       is not displayed */
		*q++ = *P++;
	    }
	    if((len > FC+COLS) && (lch == COLS - 1)) *q++ = L'$';
	    else *q++ = *P++;
	    *q = L'\0';
	    gdrawwcs(BM, p->f, fgr, pt(r.x, r.y), buff);
	} else {
	    int last;
	    wchar_t ch, chf, chl;
	    /* we don't know the string length, so modify it in place */
	    if (FC && (fch == 0)) {chf = s[FC]; s[FC] = '$';} else chf = L'\0';
	    if ((len > FC+COLS) && (lch == COLS - 1)) {
		chl = s[FC+lch]; s[FC+lch] = '$';
	    } else chl = L'\0';
	    last = FC + lch + 1;
	    if (len > last) {ch = s[last]; s[last] = L'\0';} else ch = L'\0';
	    gdrawwcs(BM, p->f, fgr, pt(r.x, r.y), &s[FC+fch]);
	    /* restore the string */
	    if (ch) s[last] = ch;
	    if (chl) s[FC+lch] = chl;
	    if (chf) s[FC] = chf;
	}
    }
}

#define WLHELPER(a, b, c, d) writelineHelper(p, a, b, c, d, j, len, s)

/* write line i of the buffer at row j on bitmap */
static int writeline(control c, ConsoleData p, int i, int j)
{
    wchar_t *s, *stmp, *p0;
    int   insel, len, col1, d;
    int   c1, c2, c3, x0, y0, x1, y1;
    rect r;
    int   bg, fg, highlight, base;

    if (p->kind == CONSOLE) base = consolebg;
    else if (p->kind == PAGER) base = pagerbg;
    else base = dataeditbg;

    bg = p->guiColors[base];
    fg = p->guiColors[base+1];
    highlight = p->guiColors[base+2];

    if ((i < 0) || (i >= NUMLINES)) return 0;
    stmp = s = LINE(i);
    len = wcswidth(stmp);
    /* If there is a \r in the line, we need to preprocess it */
    if((p0 = wcschr(s, L'\r'))) {
	int l, l1;
	stmp = LINE(i);
	s = (wchar_t *) alloca((wcslen(stmp) + 1) * sizeof(wchar_t));
	l = p0 - stmp;
	wcsncpy(s, stmp, l);
	stmp = p0 + 1;
	while((p0 = wcschr(stmp, L'\r'))) {
	    l1 = p0 - stmp;
	    wcsncpy(s, stmp, l1);
	    if(l1 > l) l = l1;
	    stmp = p0 + 1;
	}
	l1 = wcslen(stmp);
	wcsncpy(s, stmp, l1);
	if(l1 > l) l = l1;
	s[l] = L'\0';
	len = l; /* for redraw that uses len */
	/* and reset cursor position */
	{
	    wchar_t *P = s;
	    int w0;
	    for (w0 = 0; *P; P++) w0 += wcwidth(*P);
	    CURCOL = w0;
	}
    }
    col1 = COLS - 1;
    insel = p->sel ? ((i - p->my0) * (i - p->my1)) : 1;
    if (insel < 0) {
	WLHELPER(0, col1, bg, fg);
	return len;
    }
    if ((USER(i) >= 0) && (USER(i) < FC + COLS)) {
	if (USER(i) <= FC)
	    WLHELPER(0, col1, highlight, bg);
	else {
	    d = USER(i) - FC;
	    WLHELPER(0, d - 1, fg, bg);
	    WLHELPER(d, col1, highlight, bg);
	}
    } else if (USER(i) == -2) {
	WLHELPER(0, col1, highlight, bg);
    } else
	WLHELPER(0, col1, fg, bg);
    /* This is the cursor, and it may need to be variable-width */
    if ((CURROW >= 0) && (CURCOL >= FC) && (CURCOL < FC + COLS) &&
	(i == NUMLINES - 1) && (p->sel == 0 || !intersect_input(p, 0))) {
	if (!p->overwrite) {
	    if (p->cursor_blink) {
	    	setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
	    	            p->cursor_blink == 1 ? 1 : FW/4, FH);
	    	showcaret(c, 1);
	    } else showcaret(c, 0);
	    
	    if (p->cursor_blink < 2) {
	    	r = rect(BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, FW/4, FH);
	    	gfillrect(BM, highlight, r);
	    }
	} else if(mbcslocale) { /* determine the width of the current char */
	    int w0;
	    wchar_t *P = s, wc = 0, nn[2] = L" ";
	    for (w0 = 0; w0 <= CURCOL; P++) {
		wc = *P;
		if(!*P) break;
		w0 += Ri18n_wcwidth(wc);
	    }
	    /* term string '\0' box width = 1 fix */
	    w0 = wc ? Ri18n_wcwidth(wc) : 1;
	    nn[0] = wc;
	    if (p->cursor_blink) {
	    	setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
	    		    p->cursor_blink == 1 ? 1 : FW/4, FH);
	    	showcaret(c, 1);
	    } else showcaret(c, 0);
	    if (p->cursor_blink < 2) {
	    	r = rect(BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH,
		         w0 * FW, FH);
	    	gfillrect(BM, highlight, r);
	    	gdrawwcs(BM, p->f, bg, pt(r.x, r.y), nn);
	    }
	} else {
	    if (p->cursor_blink) {
		setcaret(c, BORDERX + (CURCOL - FC) * FW, BORDERY + j * FH, 
		            p->cursor_blink == 1 ? 1 : FW, FH);
	    	showcaret(c, 1);
	    } else showcaret(c, 0);
	    if (p->cursor_blink < 2) 
	    	WLHELPER(CURCOL - FC, CURCOL - FC, bg, highlight); 
	}
    }
    if (insel != 0) return len;
    c1 = (p->my0 < p->my1);
    c2 = (p->my0 == p->my1);
    c3 = (p->mx0 < p->mx1);
    if (c1 || (c2 && c3)) {
	x0 = p->mx0; y0 = p->my0;
	x1 = p->mx1; y1 = p->my1;
    } else {
	x0 = p->mx1; y0 = p->my1;
	x1 = p->mx0; y1 = p->my0;
    }
    if (i == y0) {
	if (FC + COLS < x0) return len;
	if(mbcslocale) {
	    int w0, w1 = 1;
	    wchar_t *P = s;
	    for (w0 = 0; w0 < x0; P++) {
		if(!*P) break;
		w1 = Ri18n_wcwidth(*P);
		w0 += w1;
	    }
	    if(w0 > x0) x0 = w0 - w1;
	}
	c1 = (x0 > FC) ? (x0 - FC) : 0;
    } else
	c1 = 0;
    if (i == y1) {
	if (FC > x1) return len;
	if(mbcslocale) {
	    int w0;
	    wchar_t *P = s;
	    for (w0 = 0; w0 <= x1; P++) {
		if(!*P) break;
		w0 += Ri18n_wcwidth(*P);
	    }
	    x1 = w0 - 1;
	}
	c2 = (x1 > FC + COLS) ? (COLS - 1) : (x1 - FC);
    } else
	c2 = COLS - 1;
    WLHELPER(c1, c2, bg, fg);
    return len;
}

void drawconsole(control c, rect r) /* r is unused here */
{
    ConsoleData p = getdata(c);

    int i, ll, wd, maxwd = 0;

    ll = min(NUMLINES, ROWS);
    if(!BM) return;;     /* This is a workaround for PR#1711.
			    BM should never be null here */
    if (p->kind == PAGER)
	gfillrect(BM, p->guiColors[pagerbg], getrect(BM));
    else
	gfillrect(BM, p->guiColors[consolebg], getrect(BM));
    if(!ll) return;;
    for (i = 0; i < ll; i++) {
	wd = WRITELINE(NEWFV + i, i);
	if(wd > maxwd) maxwd = wd;
    }
    RSHOW(getrect(c));
    FV = NEWFV;
    p->needredraw = 0;
/* always display scrollbar if FC > 0 */
    if(maxwd < COLS - 1) maxwd = COLS - 1;
    maxwd += FC;
    gchangescrollbar(c, HWINSB, FC, maxwd-FC, COLS,
		     p->kind == CONSOLE || NUMLINES > ROWS);
    gchangescrollbar(c, VWINSB, FV, NUMLINES - 1 , ROWS, p->kind == CONSOLE);
}

void setfirstvisible(control c, int fv)
{
    ConsoleData p = getdata(c);

    int  ds, rw, ww;

    if (NUMLINES <= ROWS) return;;
    if (fv < 0) fv = 0;
    else if (fv > NUMLINES - ROWS) fv = NUMLINES - ROWS;
    if (fv < 0) fv = 0;
    ds = fv - FV;
    if ((ds == 0) && !p->needredraw) return;;
    if (abs(ds) > 1) {
	NEWFV = fv;
	REDRAW;
	return;;
    }
    if (p->needredraw) {
	ww = min(NUMLINES, ROWS) - 1;
	rw = FV + ww;
	writeline(c, p, rw, ww);
	if (ds == 0) {
	    RSHOW(RLINE(ww));
	    return;;
	}
    }
    if (ds == 1) {
	gscroll(BM, pt(0, -FH), RMLINES(0, ROWS - 1));
	if (p->kind == PAGER)
	    gfillrect(BM, p->guiColors[pagerbg], RLINE(ROWS - 1));
	else
	    gfillrect(BM, p->guiColors[consolebg], RLINE(ROWS - 1));
	WRITELINE(fv + ROWS - 1, ROWS - 1);
    }
    else if (ds == -1) {
	gscroll(BM, pt(0, FH), RMLINES(0, ROWS - 1));
	if (p->kind == PAGER)
	    gfillrect(BM, p->guiColors[pagerbg], RLINE(0));
	else
	    gfillrect(BM, p->guiColors[consolebg], RLINE(0));
	WRITELINE(fv, 0);
    }
    RSHOW(getrect(c));
    FV = fv;
    NEWFV = fv;
    p->needredraw = 0;
    gchangescrollbar(c, VWINSB, fv, NUMLINES - 1 , ROWS, p->kind == CONSOLE);
}

void setfirstcol(control c, int newcol)
{
    ConsoleData p = getdata(c);

    int i, ml, li, ll;

    ll = (NUMLINES < ROWS) ? NUMLINES : ROWS;
    if (newcol > 0) {
	for (i = 0, ml = 0; i < ll; i++) {
	    /* <FIXME> this should really take \r into account */
	    li = wcswidth(LINE(NEWFV + i));
	    ml = (ml < li) ? li : ml;
	}
	ml = ml - COLS;
	ml = 5*(ml/5 + 1);
	if (newcol > ml) newcol = ml;
    }
    if (newcol < 0) newcol = 0;
    FC = newcol;
    REDRAW;
}

void console_mousedrag(control c, int button, point pt)
{
    ConsoleData p = getdata(c);

    pt.x -= BORDERX;
    pt.y -= BORDERY;
    if (button & LeftButton) {
	int r, s;
	r=((pt.y > 32000) ? 0 : ((pt.y > HEIGHT) ? HEIGHT : pt.y))/FH;
	s=((pt.x > 32000) ? 0 : ((pt.x > WIDTH) ? WIDTH : pt.x))/FW;
	if ((r < 0) || (r > ROWS) || (s < 0) || (s > COLS))
	    return;;
	p->my1 = FV + r;
	p->mx1 = FC + s;
	p->needredraw = 1;
	p->sel = 1;

	if (within_input(p, p->mx1, p->my1)) {
	    cur_pos = col_to_pos(p, p->mx1);
	    setCURCOL(p);
	}
	if (pt.y <= 0) setfirstvisible(c, FV - 3);
	else if (pt.y >= ROWS*FH) setfirstvisible(c, FV+3);
	if (pt.x <= 0) setfirstcol(c, FC - 3);
	else if (pt.x >= COLS*FW) setfirstcol(c, FC+3);
	else REDRAW;
    }
}

void console_mouserep(control c, int button, point pt)
{
    ConsoleData p = getdata(c);

    if ((button & LeftButton) && (p->sel)) console_mousedrag(c, button,pt);
}

void console_mousedown(control c, int button, point pt)
{
    ConsoleData p = getdata(c);

    pt.x -= BORDERX;
    pt.y -= BORDERY;
    if (p->sel) {
	p->sel = 0;
	p->needredraw = 1;
    }
    if (button & LeftButton) {
	p->my0 = FV + pt.y/FH;
	p->mx0 = FC + pt.x/FW;
	if (within_input(p, p->mx0, p->my0) ||
	    (p->my0 == CURROW && p->mx0 > prompt_wid)) {
	    cur_pos = col_to_pos(p, p->mx0);
	    setCURCOL(p);
	    p->needredraw = 1;
	}
    }
    if (p->needredraw) REDRAW;
}

void consoletogglelazy(control c)
{
    ConsoleData p = getdata(c);

    if (p->kind == PAGER) return;
    p->lazyupdate = (p->lazyupdate + 1) % 2;
}

int consolegetlazy(control c)
{
    ConsoleData p = getdata(c);
    return p->lazyupdate;
}


void consoleflush(control c)
{
    REDRAW;
}


/* These are the getline keys ^A ^E ^B ^F ^N ^P ^K ^H ^D ^U ^T ^O,
   plus ^Z for EOF.

   We also use ^C ^V/^Y ^X (copy/paste/both) ^W ^L
*/
#define BEGINLINE 1
#define ENDLINE   5
#define CHARLEFT 2
#define CHARRIGHT 6
#define NEXTHISTORY 14
#define PREVHISTORY 16
#define KILLRESTOFLINE 11
#define BACKCHAR  8
#define DELETECHAR 4
#define KILLLINE 21
#define CHARTRANS 20
#define OVERWRITE 15
#define EOFKEY 26

/* ^I for completion */

#define TABKEY 9

/* free ^G ^Q ^R ^S, perhaps ^J */

static void checkpointpos(xbuf p, int save)
{
    static int ns, av;
    static wchar_t *free;
    if(save) {
	ns = p->ns;
	av = p->av;
	free = p->free;
    } else {
	p->ns = ns;
	p->av = av;
	p->free = free;
    }
}

static void storekey(control c, int k)
{
    ConsoleData p = getdata(c);

    if (p->wipe_completion) {
	p->wipe_completion = 0;
	checkpointpos(p->lbuf, 0);
	/* mark whole of current line as user input */
	USER(NUMLINES-1) = 0;
	p->needredraw = 1;
	REDRAW;
    }
    if (p->kind == PAGER) return;
    if (k == BKSP) k = BACKCHAR;
    if (k == TABKEY) {
	performCompletion(c);
	return;
    }
    if (p->numkeys >= NKEYS) {
	gabeep();
	return;;
    }
    p->kbuf[(p->firstkey + p->numkeys) % NKEYS] = k;
    p->numkeys++;
}

static void storetab(control c)
{
    ConsoleData p = getdata(c);
    p->kbuf[(p->firstkey + p->numkeys) % NKEYS] = L' ';
    p->numkeys++;
}


#include <Rinternals.h>
#include <R_ext/Parse.h>

static int completion_available = -1;

void set_completion_available(int x)
{
    completion_available = x;
}


static void performCompletion(control c)
{
    ConsoleData p = getdata(c);
    int i, alen, alen2, max_show = 10, cursor_position = CURCOL - prompt_wid;
    wchar_t *partial_line = LINE(NUMLINES - 1) + prompt_wid;
    const char *additional_text;
    SEXP cmdSexp, cmdexpr, ans = R_NilValue;
    ParseStatus status;

    if(!completion_available) {
	storetab(c);
	return;
    }

    if(completion_available < 0) {
	char *p = getenv("R_COMPLETION");
	if(p && strcmp(p, "FALSE") == 0) {
	    completion_available = 0;
	    storetab(c);
	    return;
	}
	/* First check if namespace is loaded */
	if(findVarInFrame(R_NamespaceRegistry, install("utils"))
	   != R_UnboundValue) completion_available = 1;
	else { /* Then try to load it */
	    char *p = "try(loadNamespace('utils'), silent=TRUE)";
	    PROTECT(cmdSexp = mkString(p));
	    cmdexpr = PROTECT(R_ParseVector(cmdSexp, -1, &status, R_NilValue));
	    if(status == PARSE_OK) {
		for(i = 0; i < length(cmdexpr); i++)
		    eval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv);
	    }
	    UNPROTECT(2);
	    if(findVarInFrame(R_NamespaceRegistry, install("utils"))
	       != R_UnboundValue) completion_available = 1;
	    else {
		completion_available = 0;
		return;
	    }
	}
    }

    alen = wcslen(partial_line);
    wchar_t orig[alen + 1], pline[2*alen + 1],
            *pchar = pline, achar;
    wcscpy(orig, partial_line);
    for (i = 0; i < alen; i++) {
        achar = orig[i];
	if (achar == '"' || achar == '\\') *pchar++ = '\\';
	*pchar++ = achar;
    }
    *pchar = 0;
    size_t len = wcslen(pline) + 100; 
    char cmd[len];
    snprintf(cmd, len, "utils:::.win32consoleCompletion(\"%ls\", %d)",
	     pline, cursor_position);
    PROTECT(cmdSexp = mkString(cmd));
    cmdexpr = PROTECT(R_ParseVector(cmdSexp, -1, &status, R_NilValue));
    if (status != PARSE_OK) {
	UNPROTECT(2);
	/* Uncomment next line to debug */
	/* Rprintf("failed: %s \n", cmd); */
	/* otherwise pretend that nothing happened and return */
	return;
    }
    /* Loop is needed here as EXPSEXP will be of length > 1 */
    for(i = 0; i < length(cmdexpr); i++)
	ans = eval(VECTOR_ELT(cmdexpr, i), R_GlobalEnv);
    UNPROTECT(2);

    /* ans has the form list(addition, possible), where 'addition' is
       unique additional text if any, and 'possible' is a character
       vector holding possible completions if any (already formatted
       for linewise printing in the current implementation).  If
       'possible' has any content, we want to print those (or show in
       status bar or whatever).  Otherwise add the 'additional' text
       at the cursor */

#define ADDITION 0
#define POSSIBLE 1

    alen = length(VECTOR_ELT(ans, POSSIBLE));
    additional_text = CHAR(STRING_ELT( VECTOR_ELT(ans, ADDITION), 0 ));
    alen2 = strlen(additional_text);
    if (alen) {
	/* make a copy of the current string first */
	wchar_t p1[wcslen(LINE(NUMLINES - 1)) + 1];
	wcscpy(p1, LINE(NUMLINES - 1));
	checkpointpos(p->lbuf, 1);
	size_t len = MB_CUR_MAX * wcslen(p1) + 1; 
	char buf1[len+1];
	snprintf(buf1, len+1, "%ls\n", p1);
	consolewrites(c, buf1);

	for (i = 0; i < min(alen, max_show); i++) {
            consolewrites(c, "\n");
	    consolewrites(c, CHAR(STRING_ELT(VECTOR_ELT(ans, POSSIBLE), i)));
	}
	if (alen > max_show)
	    consolewrites(c, "\n[...truncated]");
	consolewrites(c, "\n");
	p->wipe_completion = 1;
    }

    if (alen2)
	for (i = 0; i < alen2; i++) storekey(c, additional_text[i]);
    return;
}

/* deletes that part of the selection which is on the input line */
static void deleteselected(ConsoleData p)
{
    if (p->sel) {
	int s0, s1;
	wchar_t *cur_line;
	if (intersect_input(p, 1)) {
	    /* convert to bytes after the prompt */
	    s0 = col_to_pos(p, p->mx0);
	    s1 = col_to_pos(p, p->mx1);
	    cur_line = LINE(CURROW) + prompt_len;
	    for(int i = s0; i <= max_pos; i++)
		cur_line[i] = cur_line[i + s1 - s0 + 1];
	    max_pos -= s1 - s0 + 1;
	    cur_line[max_pos] = L'\0';
	    if (cur_pos > s0)
		cur_pos = cur_pos > s1 ? cur_pos - (s1 - s0 + 1) : s0;
	    setCURCOL(p);
	    p->needredraw = 1;
	}
    }
}

/* cmd is in native encoding */
void consolecmd(control c, const char *cmd)
{
    ConsoleData p = getdata(c);

    int i;
    if (p->sel) {
	deleteselected(p);
	p->sel = 0;
	p->needredraw = 1;
	REDRAW;
    }
    storekey(c, BEGINLINE);
    storekey(c, KILLRESTOFLINE);
    if(isUnicodeWindow(c)) {
	size_t sz = (strlen(cmd) + 1) * sizeof(wchar_t);
	wchar_t *wcs = (wchar_t*) R_alloc(strlen(cmd) + 1, sizeof(wchar_t));
	memset(wcs, 0, sz);
	mbstowcs(wcs, cmd, sz-1);
	for(i = 0; wcs[i]; i++) storekey(c, wcs[i]);
    } else {
	const char *ch;
	for (ch = cmd; *ch; ch++) storekey(c, (unsigned char) *ch);
    }
    storekey(c, '\n');
/* if we are editing we save the actual line
   FIXME: not right if Unicode */
    if (CURROW > -1) {
	char buf[2000], *cp; /* maximum 2 bytes/char */
	wchar_t *wc = &(LINE(NUMLINES - 1)[prompt_len]);
	memset(buf, 0, 2000);
	wcstombs(buf, wc, 1000);
	for (cp = buf; *cp; cp++) storekey(c, *cp);
	for (i = max_pos; i > cur_pos; i--) storekey(c, CHARLEFT);
    }
}

static int CleanTranscript(wchar_t *tscpt, wchar_t *cmds)
{
    /*
     * Filter R commands out of a string that contains
     * prompts, commands, and output.
     * Uses a simple algorithm that just looks for '>'
     * prompts and '+' continuation following a simple prompt prefix.
     * Always return the length of the string required
     * to hold the filtered commands.
     * If cmds is a non-null pointer, write the commands
     * to cmds & terminate with null.
     */
    int incommand = 0, startofline = 1, len = 0;
    wchar_t nonprefix[] = L">+ \t\n\r";
    while (*tscpt) {
	if (startofline) {
	    /* skip initial whitespace */
	    while (*tscpt == L' ' || *tscpt == L'\t') tscpt++;
	    /* skip over the prompt prefix */
	    while (*tscpt && !wcschr(nonprefix, *tscpt)) tscpt++;
	    if (*tscpt == L'>' || (incommand && *tscpt == L'+')) {
		tscpt++;
		if (*tscpt == L' ' || *tscpt == L'\t') tscpt++;
		incommand = 1;
	    } else {
		incommand = 0;
	    }
	    startofline = 0;
	} else {
	    if (incommand) {
		if (cmds) *(cmds++) = *tscpt;
		len++;
	    }
	    if (*tscpt == L'\n') startofline = 1;
	    tscpt++;
	}
    }
    if (cmds) {
	/* seem to have to terminate with two nulls, otherwise
	   pasting empty commands doesn't work correctly (e.g.,
	   when clipboard contains 'XXX') */
	*cmds = '\0';
	*(cmds+1) = '\0';
    }
    return(len+2);
}

/* Send a single newline to the console */
void consolenewline(control c)
{
    storekey(c, '\n');
}

/* the following four routines are system dependent */
void consolepaste(control c)
{
    ConsoleData p = getdata(c);

    HGLOBAL hglb;
    wchar_t *pc, *new = NULL;
    if (p->sel) {
	deleteselected(p);
	p->sel = 0;
	p->needredraw = 1;
	REDRAW;
     }
    if (p->kind == PAGER) return;
    if ( OpenClipboard(NULL) &&
	 (hglb = GetClipboardData(CF_UNICODETEXT)) &&
	 (pc = (wchar_t *) GlobalLock(hglb)))
    {
	if (p->clp) {
	   new = realloc((void *)p->clp,
			 (wcslen(p->clp) + wcslen(pc) + 1) * sizeof(wchar_t));
	}
	else {
	   new = malloc((wcslen(pc) + 1) * sizeof(wchar_t)) ;
	   if (new) new[0] = L'\0';
	   p->already = p->numkeys;
	   p->pclp = 0;
	}
	if (new) {
	   int i;
	   p->clp = new;
	   /* Surrogate Pairs Block */
	   for (i = 0; i < wcslen(pc); i++)
	       if (IsSurrogatePairsHi(pc[i]) && i+1 < wcslen(pc) &&
		    IsSurrogatePairsLo(pc[i+1]) ) {
		   pc[i] = L'?';
		   pc[i+1] = L'?';
		   i++;
	       }
	   wcscat(p->clp, pc);
	}
	else {
	   R_ShowMessage(G_("Not enough memory"));
	}
	GlobalUnlock(hglb);
    }
    CloseClipboard();
}

void consolepastecmds(control c)
{
    ConsoleData p = getdata(c);

    HGLOBAL hglb;
    wchar_t *pc, *new = NULL;
    if (p->sel) {
	deleteselected(p);
	p->sel = 0;
	p->needredraw = 1;
	REDRAW;
     }
    if (p->kind == PAGER) return;;
    if ( OpenClipboard(NULL) &&
	 (hglb = GetClipboardData(CF_UNICODETEXT)) &&
	 (pc = (wchar_t *) GlobalLock(hglb)))
    {
	if (p->clp) {
	    new = realloc((void *)p->clp,
			  (wcslen(p->clp) + CleanTranscript(pc, 0))
			  * sizeof(wchar_t));
	}
	else {
	    new = malloc(CleanTranscript(pc, 0) * sizeof(wchar_t));
	    if (new) new[0] = '\0';
	    p->already = p->numkeys;
	    p->pclp = 0;
	}
	if (new) {
	    p->clp = new;
	    /* copy just the commands from the clipboard */
	    for (; *new; ++new); /* append to the end of 'new' */
	    CleanTranscript(pc, new);
	}
	else {
	    R_ShowMessage(G_("Not enough memory"));
	}
	GlobalUnlock(hglb);
    }
    CloseClipboard();
}

/* This works with columns, not chars or bytes */
static void consoletoclipboardHelper(control c, int x0, int y0, int x1, int y1)
{
    ConsoleData p = getdata(c);

    HGLOBAL hglb;
    int ll, i, j;
    wchar_t *s;

    if(mbcslocale) {
	int w0, x00 = x0, x11=100000;
	i = y0; ll = 1; /* terminator */
	while (i <= y1) {
	    wchar_t *P = LINE(i);
	    for (w0 = 0; w0 < x00 && *P; P++) w0 += Ri18n_wcwidth(*P);
	    x00 = 0;
	    if(i == y1) x11 = x1+1; /* cols are 0-based */
	    while (w0 < x11 && *P) {
		ll++;
		w0 += Ri18n_wcwidth(*P++);
	    }
	    if(w0 < x11) ll += 2;  /* \r\n */
	    i++;
	}
    } else {
	i = y0; j = x0; ll = 1; /* terminator */
	while ((i < y1) || ((i == y1) && (j <= x1))) {
	    if (LINE(i)[j]) {
		ll++;
		j++;
	    } else {
		ll += 2;
		i++;
		j = 0;
	    }
	}
    }


    if (!(hglb = GlobalAlloc(GHND, ll * sizeof(wchar_t)))){
	R_ShowMessage(G_("Insufficient memory: text not copied to the clipboard"));
	return;
    }
    if (!(s = (wchar_t *)GlobalLock(hglb))){
	R_ShowMessage(G_("Insufficient memory: text not copied to the clipboard"));
	return;
    }
    if(mbcslocale) {
	int w0, x00 = x0, x11=100000;
	wchar_t *P;
	i = y0;
	while (i <= y1) {
	    P = LINE(i);
	    for (w0 = 0; w0 < x00 && *P; P++) w0 += Ri18n_wcwidth(*P);
	    x00 = 0;
	    if(i == y1) x11 = x1+1;
	    while (w0 < x11 && *P) {
		w0 += Ri18n_wcwidth(*P);
		*s++ = *P++;
	    }
	    if(w0 < x11) {
		*s++ = L'\r'; *s++ = L'\n';
	    }
	    i++;
	}
    } else {
	i = y0; j = x0;
	while ((i < y1) || ((i == y1) && (j <= x1))) {
	    wchar_t ch = LINE(i)[j];
	    if (ch) {
		*s++ = ch;
		j++;
	    } else {
		*s++ = L'\r'; *s++ = L'\n';
		i++;
		j = 0;
	    }
	}
    }
    *s = L'\0';
    GlobalUnlock(hglb);
    if (!OpenClipboard(NULL) || !EmptyClipboard()) {
	R_ShowMessage(G_("Unable to open the clipboard"));
	GlobalFree(hglb);
	return;;
    }
    SetClipboardData(CF_UNICODETEXT, hglb);
    CloseClipboard();
}

/* end of system dependent part */

int consolecanpaste(control c)
{
    return clipboardhastext();
}


int consolecancopy(control c)
{
    ConsoleData p = getdata(c);
    return p->sel;
}


void consolecopy(control c)
{
    ConsoleData p = getdata(c);

    if (p->sel) {
	int len, c1, c2, c3;
	int x0, y0, x1, y1;
	if (p->my0 >= NUMLINES) p->my0 = NUMLINES - 1;
	if (p->my0 < 0) p->my0 = 0;
	len = wcswidth(LINE(p->my0));
	if (p->mx0 >= len) p->mx0 = len - 1;
	if (p->mx0 < 0) p->mx0 = 0;
	if (p->my1 >= NUMLINES) p->my1 = NUMLINES - 1;
	if (p->my1 < 0) p->my1 = 0;
	len = wcswidth(LINE(p->my1));
	if (p->mx1 >= len) p->mx1 = len/* - 1*/;
	if (p->mx1 < 0) p->mx1 = 0;
	c1 = (p->my0 < p->my1);
	c2 = (p->my0 == p->my1);
	c3 = (p->mx0 < p->mx1);
	if (c1 || (c2 && c3)) {
	   x0 = p->mx0; y0 = p->my0;
	   x1 = p->mx1; y1 = p->my1;
	}
	else {
	   x0 = p->mx1; y0 = p->my1;
	   x1 = p->mx0; y1 = p->my0;
	}
	consoletoclipboardHelper(c, x0, y0, x1, y1);
	REDRAW;
    }
}

void consoleselectall(control c)
{
    ConsoleData p = getdata(c);

   if (NUMLINES) {
       p->sel = 1;
       p->my0 = p->mx0 = 0;
       p->my1 = NUMLINES - 1;
       p->mx1 = wcslen(LINE(p->my1));
       REDRAW;
    }
}

/*
   This works in CJK as the IME puts CJK characters in the
   input buffer as 2 bytes, and they are retrieved successively
*/
void console_normalkeyin(control c, int k)
{
    ConsoleData p = getdata(c);

    int st;

    st = ggetkeystate();
    if ((p->chbrk) && (k == p->chbrk) &&
	((!p->modbrk) || ((p->modbrk) && (st == p->modbrk)))) {
	p->fbrk(c);
	return;
    }
    if (st == CtrlKey)
	switch (k + 'A' - 1) {
	    /* most are stored as themselves */
	case 'C':
	    consolecopy(c);
	    st = -1;
	    break;
	case 'V':
	case 'Y':
	    if(p->kind == PAGER) {
		consolecopy(c);
		if (CharacterMode == RGui) consolepaste(RConsole);
	    }
	    else consolepaste(c);
	    st = -1;
	    break;
	case 'X':
	    consolecopy(c);
	    consolepaste(c);
	    st = -1;
	    break;
	case 'W':
	    consoletogglelazy(c);
	    st = -1;
	    break;
	case 'L':
	    consoleclear(c);
	    st = -1;
	    break;
	case 'O':
	    p->overwrite = !p->overwrite;
	    p->needredraw = 1;
	    st = -1;
	    break;
	}
    if (p->sel) {
	if (st != -1) deleteselected(p);
	p->needredraw = 1;
	p->sel = 0;
    }
    if (p->needredraw) REDRAW;
    if (st == -1) return;
    if (p->kind == PAGER) {
	if(k == 'q' || k == 'Q') pagerbclose(c);
	if(k == ' ') setfirstvisible(c, NEWFV + ROWS);
	if(k == '-') setfirstvisible(c, NEWFV - ROWS);
	if(k == 'F' - 'A' + 1) setfirstvisible(c, NEWFV + ROWS);
	if(k == 'B' - 'A' + 1) setfirstvisible(c, NEWFV - ROWS);
	if(k == 1) consoleselectall(c);
	return;
    }
    storekey(c, k);
}

void console_ctrlkeyin(control c, int key)
{
    ConsoleData p = getdata(c);

    int st;

    st = ggetkeystate();
    if ((p->chbrk) && (key == p->chbrk) &&
	((!p->modbrk) || ((p->modbrk) && (st == p->modbrk)))) {
	p->fbrk(c);
	return;
    }
    switch (key) {
     case PGUP: setfirstvisible(c, NEWFV - ROWS); break;
     case PGDN: setfirstvisible(c, NEWFV + ROWS); break;
     case HOME:
	 if (st == CtrlKey)
	     setfirstvisible(c, 0);
	 else
	     if (p->kind == PAGER)
		 setfirstcol(c, 0);
	     else
		 storekey(c, BEGINLINE);
	 break;
     case END:
	 if (st == CtrlKey)
	     setfirstvisible(c, NUMLINES);
	 else
	     storekey(c, ENDLINE);
	 break;
     case UP:
	 if ((st == CtrlKey) || (p->kind == PAGER))
	     setfirstvisible(c, NEWFV - 1);
	 else
	     storekey(c, PREVHISTORY);
	 break;
     case DOWN:
	 if ((st == CtrlKey) || (p->kind == PAGER))
	     setfirstvisible(c, NEWFV + 1);
	 else
	     storekey(c, NEXTHISTORY);
	 break;
     case LEFT:
	 if ((st == CtrlKey) || (p->kind == PAGER))
	     setfirstcol(c, FC - 5);
	 else
	     storekey(c, CHARLEFT);
	 break;
     case RIGHT:
	 if ((st == CtrlKey) || (p->kind == PAGER))
	     setfirstcol(c, FC + 5);
	 else
	     storekey(c, CHARRIGHT);
	 break;
     case DEL:
	 if (p->sel) {
	     if (st == ShiftKey) consolecopy(c);
	     deleteselected(p);
	     p->sel = 0;
	 } else  if (st == CtrlKey)
	     storekey(c, KILLRESTOFLINE);
	 else
	     storekey(c, DELETECHAR);
	 break;
     case ENTER:
	 deleteselected(p);
	 storekey(c, '\n');
	 break;
     case INS:
	 if (st == ShiftKey) {
	     deleteselected(p);
	     consolepaste(c);
	 } else {
	     p->overwrite = !p->overwrite;
	     p->needredraw = 1;
	 }
	 break;
    }
    if (p->sel) {
	p->sel = 0;
	p->needredraw = 1;
    }
    if (p->needredraw) REDRAW;
}

static Rboolean incomplete = FALSE;
int consolewrites(control c, const char *s)
{
    ConsoleData p = getdata(c);

    wchar_t buf[1001];
    if(p->input) {
	int i, len = wcslen(LINE(NUMLINES - 1));
	/* save the input line */
	wcsncpy(buf, LINE(NUMLINES - 1), 1000);
	buf[1000] = L'\0';
	/* now zap it */
	for(i = 0; i < len; i++) xbufaddxc(p->lbuf, L'\b');
	if (incomplete) {
	    NUMLINES--;
	    p->lbuf->free--;
	    p->lbuf->av++;
	}
	USER(NUMLINES - 1) = -1;
    }
    xbufadds(p->lbuf, s, 0);
    FC = 0;
    if(p->input) {
	incomplete = (s[strlen(s) - 1] != '\n');
	if (incomplete) xbufaddxc(p->lbuf, L'\n');
	xbufaddxs(p->lbuf, buf, 1);
    }
    if (strchr(s, '\n')) p->needredraw = 1;
    if (!p->lazyupdate) {
	setfirstvisible(c, NUMLINES - ROWS);
	REDRAW;
    } else if (CURROW >= 0)
	setfirstvisible(c, NUMLINES - ROWS);
    else {
	NEWFV = NUMLINES - ROWS;
	if (NEWFV < 0) NEWFV = 0;
    }
    if(p->input) REDRAW;
    return 0;
}

void freeConsoleData(ConsoleData p)
{
    if (!p) return;
    if (BM) del(BM);
    if (p->kind == CONSOLE) {
	if (p->lbuf) xbufdel(p->lbuf);
	if (p->kbuf) free(p->kbuf);
    }
    free(p);
}

static void delconsole(control c)
{
    freeConsoleData(getdata(c));
}

/* console readline (coded looking to the GNUPLOT 3.5 readline)*/
static wchar_t consolegetc(control c)
{
    ConsoleData p;
    wchar_t ch;

    p = getdata(c);
    while((p->numkeys == 0) && (!p->clp))
    {
	R_WaitEvent();
	R_ProcessEvents();
    }
    if (p->sel) {
	deleteselected(p);
	p->sel = 0;
	p->needredraw = 1;
	setCURCOL(p); /* Needed? */
	REDRAW;
    }
    if (!p->already && p->clp) {
	ch = p->clp[p->pclp++];
	if (!(p->clp[p->pclp])) {
	    free(p->clp);
	    p->clp = NULL;
	}
    } else {
	if(isUnicodeWindow(c)) {
	    ch = p->kbuf[p->firstkey];
	    p->firstkey = (p->firstkey + 1) % NKEYS;
	    p->numkeys--;
	    if (p->already) p->already--;
	} else {
	    /* Will not work for stateful encodings */
	    mbstate_t mb_st;
	    memset(&mb_st, 0, sizeof(mbstate_t));
	    if(mbcslocale) {
		/* Possibly multiple 'keys' for a single keystroke */
		char tmp[20];
		unsigned int used, i;

		for(i = 0; i < MB_CUR_MAX; i++)
		    tmp[i] = p->kbuf[(p->firstkey + i) % NKEYS];
		used = mbrtowc(&ch, tmp, MB_CUR_MAX, &mb_st);
		p->firstkey = (p->firstkey + used) % NKEYS;
		p->numkeys -= used;
		if (p->already) p->already -= used;
	    } else {
		ch = (unsigned char) p->kbuf[p->firstkey];
		if(ch >=128) {
		    char tmp[2] = " ";
		    tmp[0] = ch;
		    mbrtowc(&ch, tmp, 2, &mb_st);
		}
		p->firstkey = (p->firstkey + 1) % NKEYS;
		p->numkeys--;
		if (p->already) p->already--;
	    }
	}
    }
    return ch;
}

static void consoleunputc(control c)
{
    ConsoleData p = getdata(c);

    if(p->clp) p->pclp--;
    else {
	p->numkeys += 1;
	if (p->firstkey > 0) p->firstkey -= 1;
	else p->firstkey = NKEYS - 1;
    }
}

/* This scrolls as far left as possible */
static void checkvisible(control c)
{
    ConsoleData p = getdata(c);

    int newfc;

    setfirstvisible(c, NUMLINES-ROWS);
    newfc = 0;
    while ((CURCOL <= newfc) || (CURCOL > newfc+COLS-2)) newfc += 5;
    if (newfc != FC) setfirstcol(c, newfc);
}

static void draweditline(control c)
{
    ConsoleData p = getdata(c);
    setCURCOL(p);
    checkvisible(c);
    if (p->needredraw) {
	REDRAW;
    } else {
	WRITELINE(NUMLINES - 1, CURROW);
	RSHOW(RLINE(CURROW));
    }
}

/* This needs to convert the nul-terminated wchar_t string 'in' to a
   sensible strinf in buf[len].  It must not be empty, as R will
   interpret that as EOF, and it should end in \n, as 'in' should do.

   Our strategy is to convert character by character to the current
   Windows locale, using \uxxxx escapes for invalid characters.
*/

static void wcstobuf(char *buf, int len, const wchar_t *in)
{
    int used, tot = 0;
    char *p = buf, tmp[7];
    const wchar_t *wc = in;
    wchar_t wc_check;
    mbstate_t mb_st;

    for(; wc; wc++, p+=used, tot+=used) {
	if(tot >= len - 2) break;
	used = wctomb(p, *wc);
	if (used >= 0) {
	    /* conversion was successful, but check that converting back gets
	       the original result (it does not with best-fit transliteration)
	       NOTE: WideCharToMultiByte may be faster */
	    memset(&mb_st, 0, sizeof(mbstate_t));
	    if (mbrtowc(&wc_check, p, used, &mb_st) < 0 || wc_check != *wc) 
		used = -1;
	}
	if (used < 0) {
	    snprintf(tmp, 7, "\\u%x", *wc);
	    used = strlen(tmp);
	    memcpy(p, tmp, used);
	}
    }
    *p++ = '\n'; *p = '\0';
}

int consolereads(control c, const char *prompt, char *buf, int len,
		 int addtohistory)
{
    ConsoleData p = getdata(c);

    wchar_t *cur_line, *P;
    wchar_t *aLine;
    int ns0 = NUMLINES, w0 = 0, pre_prompt_len;

    pre_prompt_len = wcslen(LINE(NUMLINES - 1));
    /* print the prompt */
    xbufadds(p->lbuf, prompt, 1);
    if (!xbufmakeroom(p->lbuf, len + 1)) return 1;
    P = aLine = LINE(NUMLINES - 1);
    prompt_len = wcslen(aLine);
    for (; P < aLine + pre_prompt_len; P++)
	if(*P == L'\r') w0 = 0;
	else w0 += mbcslocale ? Ri18n_wcwidth(*P) : 1;
    USER(NUMLINES - 1) = w0;
    prompt_wid = wcswidth(aLine);
    if (NUMLINES > ROWS) {
	CURROW = ROWS - 1;
	NEWFV = NUMLINES - ROWS;
    } else {
	CURROW = NUMLINES - 1;
	NEWFV = 0;
    }
    CURCOL = prompt_wid;
    FC = 0;
    cur_pos = 0;
    max_pos = 0;
    cur_line = &aLine[prompt_len];
    cur_line[0] = L'\0';
    showcaret(c, 1);
    REDRAW;
    for(;;) {
	wchar_t cur_char;
	char chtype; /* boolean */
	p->input = 1;
	cur_char = consolegetc(c);
	p->input = 0;
	chtype = ((unsigned int) cur_char > 0x1f);
	if(NUMLINES != ns0) { /* we scrolled, e.g. cleared screen */
	    cur_line = LINE(NUMLINES - 1) + prompt_len;
	    ns0 = NUMLINES;
	    if (NUMLINES > ROWS) {
		CURROW = ROWS - 1;
		NEWFV = NUMLINES - ROWS;
	    } else {
		CURROW = NUMLINES - 1;
		NEWFV = 0;
	    }
	    USER(NUMLINES - 1) = prompt_wid;
	    p->needredraw = 1;
	}
	if(chtype && (max_pos <= len - 2)) {
	    /* not a control char: we need to fit in the char\n\0 */
	    int i;
	    if(!p->overwrite) {
		for(i = max_pos; i > cur_pos; i--)
		    cur_line[i] = cur_line[i - 1];
	    }
	    cur_line[cur_pos] = cur_char;
	    if(!p->overwrite || cur_pos == max_pos) {
		max_pos += 1;
		cur_line[max_pos] = L'\0';
	    }
	    cur_pos++;
	} else { /* a control char */
	    /* do normal editing commands */
	    int i;
	    switch(cur_char) {
	    case BEGINLINE:
		cur_pos = 0;
		break;
	    case CHARLEFT:
		if(cur_pos > 0) cur_pos--;
		break;
	    case ENDLINE:
		cur_pos = max_pos;
		break;
	    case CHARRIGHT:
		if(cur_pos < max_pos) cur_pos ++;
		break;
	    case KILLRESTOFLINE:
		max_pos = cur_pos;
		cur_line[max_pos] = L'\0';
		break;
	    case KILLLINE:
		max_pos = cur_pos = 0;
		cur_line[max_pos] = L'\0';
		break;
	    case PREVHISTORY:
		P = wgl_hist_prev();
		xbufmakeroom(p->lbuf, wcslen(P) + 1);
		wcscpy(cur_line, P);
		cur_pos = max_pos = wcslen(cur_line);
		break;
	    case NEXTHISTORY:
		P = wgl_hist_next();
		xbufmakeroom(p->lbuf, wcslen(P) + 1);
		wcscpy(cur_line, P);
		cur_pos = max_pos = wcslen(cur_line);
		break;
	    case BACKCHAR:
		if(cur_pos > 0) {
		    cur_pos--;
		    for(i = cur_pos; i <= max_pos - 1; i++)
			cur_line[i] = cur_line[i + 1];
		    max_pos--;
		}
		break;
	    case DELETECHAR:
		if(max_pos == 0) break;
		if(cur_pos < max_pos) {
		    for(i = cur_pos; i <= max_pos - 1; i++)
			cur_line[i] = cur_line[i + 1];
		    max_pos--;
		}
		break;
	    case CHARTRANS:
		if(cur_pos < 1) break;
		if(cur_pos >= max_pos) break;
		cur_char = cur_line[cur_pos];
		cur_line[cur_pos] = cur_line[cur_pos-1];
		cur_line[cur_pos-1] = cur_char;
		break;
	    default:   /* Another control char, or overflow */
		if (chtype || (cur_char == L'\n') || (cur_char == EOFKEY)) {
		    if (chtype) {
			if (cur_pos == max_pos) {
			    consoleunputc(c);
			} else {
			    gabeep();
			    break;
			}
		    }
		    if((cur_char == L'\n') || (cur_char == EOFKEY)) {
			cur_line[max_pos] = L'\n';
			cur_line[max_pos + 1] = L'\0';
		    } else
			cur_line[max_pos] = L'\0';
		    wcstobuf(buf, len, cur_line);
		    //sprintf(buf, "%ls", cur_line);
		    //if(strlen(buf) == 0) strcpy(buf, "invalid input\n");
		    CURROW = -1;
		    cur_line[max_pos] = L'\0';
		    if (max_pos && addtohistory) wgl_histadd(cur_line);
		    xbuffixl(p->lbuf);
		    consolewrites(c, "\n");
		    showcaret(c, 0);
		    REDRAW;
		    return cur_char == EOFKEY;
		}
		break;
	    }
	}
	draweditline(c);
    }
}

void console_sbf(control c, int pos)
{
    ConsoleData p = getdata(c);

    if (pos < 0) {
	pos = -pos - 1 ;
	if (FC != pos) setfirstcol(c, pos);
    } else
	if (FV != pos) setfirstvisible(c, pos);
}

void console_im(control c, font *f, point *pt)
{
  ConsoleData p = getdata(c);
  pt->x = BORDERX + CURCOL * FW;
  pt->y = BORDERY + CURROW * FH;
  *f = consolefn;
}

void Rconsolesetwidth(int);
int setWidthOnResize = 0;

int consolecols(console c)
{
    ConsoleData p = getdata(c);

    return COLS;
}

void consoleresize(console c, rect r)
{
    ConsoleData p = getdata(c);

    int rr, pcols = COLS;

    if (((WIDTH  == r.width) &&
	 (HEIGHT == r.height)) ||
	(r.width == 0) || (r.height == 0) ) /* minimize */
	return;;
/*
 *  set first visible to keep the bottom line on a console,
 *  the middle line on a pager
 */
    if (p->kind == CONSOLE) rr = FV + ROWS;
    else rr = FV + ROWS/2;
    ROWS = r.height/FH - 1;
    if (p->kind == CONSOLE) rr -= ROWS;
    else rr -= ROWS/2;
    COLS = r.width/FW - 1;
    WIDTH = r.width;
    HEIGHT = r.height;
    BORDERX = (WIDTH - COLS*FW) / 2;
    BORDERY = (HEIGHT - ROWS*FH) / 2;
    NEWFV = NUMLINES - ROWS;
    if (NEWFV < 0) NEWFV = 0;
    del(BM);
    BM = newbitmap(r.width, r.height, 2);
    if (!BM) {
       R_ShowMessage(G_("Insufficient memory. Please close the console"));
       return ;
    }
    if(!p->lbuf) return;;    /* don't implement resize if no content
				   yet in pager */
    if (CURROW >= 0) {
	if (NUMLINES > ROWS) {
	    CURROW = ROWS - 1;
	} else
	    CURROW = NUMLINES - 1;
    }
    clear(c);
    p->needredraw = 1;
    setfirstvisible(c, rr);
    if (setWidthOnResize && p->kind == CONSOLE && COLS != pcols)
	Rconsolesetwidth(COLS);
}

void consolesetbrk(console c, actionfn fn, char ch, char mod)
{
    ConsoleData p = getdata(c);

    p->chbrk = ch;
    p->modbrk = mod;
    p->fbrk = fn;
}

font consolefn = NULL;
char fontname[LF_FACESIZE+4];
int fontsty, pointsize;
int consoler = 25, consolec = 80, consolex = 0, consoley = 0;
int pagerrow = 25, pagercol = 80;
int pagerMultiple = 1, haveusedapager = 0;
int consolebufb = DIMLBUF, consolebufl = MLBUF, consolebuffered = 1;
static int consoleblink = 1;

void
setconsoleoptions(const char *fnname,int fnsty, int fnpoints,
		  int rows, int cols, int consx, int consy,
		  rgb *nguiColors,
		  int pgr, int pgc, int multiplewindows, int widthonresize,
		  int bufbytes, int buflines, int buffered, int cursor_blink)
{
    char msg[LF_FACESIZE + 128];
    strncpy(fontname, fnname, LF_FACESIZE);
    fontname[LF_FACESIZE] = L'\0';
    fontsty =   fnsty;
    pointsize = fnpoints;
    if (consolefn) del(consolefn);
    consolefn = NULL;
    if (strcmp(fontname, "FixedFont")) {
	consolefn = gnewfont(NULL, fnname, fnsty | FixedWidth, fnpoints, 0.0, 1);
	if (!consolefn) {
	    /* This is unlikely to happen: it will find some match */
	    snprintf(msg, LF_FACESIZE + 128,
		     G_("Font %s-%d-%d  not found.\nUsing system fixed font"),
		     fontname, fontsty | FixedWidth, pointsize);
	    R_ShowMessage(msg);
	    consolefn = FixedFont;
	}
    }
/*    if (!ghasfixedwidth(consolefn)) {
       sprintf(msg,
	       "Font %s-%d-%d has variable width.\nUsing system fixed font.",
	       fontname, fontsty, pointsize);
       R_ShowMessage(msg);
       consolefn = FixedFont;
       } */
    consoler = rows;
    consolec = cols;
    consolex = consx;
    consoley = consy;
    for (int i=0; i<numGuiColors; i++)
	guiColors[i] = nguiColors[i];
    pagerrow = pgr;
    pagercol = pgc;
    pagerMultiple = multiplewindows;
    setWidthOnResize = widthonresize;
    consolebufb = bufbytes;
    consolebufl = buflines;
    consolebuffered = buffered;
    consoleblink = cursor_blink;
}

void consoleprint(console c)
{
    ConsoleData p = getdata(c);


    printer lpr;
    int cc, rr, fh, cl, cp, clinp, i;
    int top, left;
    int x0, y0, x1, y1;
    font f;
    wchar_t *s = L"";
    char msg[LF_FACESIZE + 128], title[60];
    wchar_t buf[1024];
    cursor cur;
    if (!(lpr = newprinter(0.0, 0.0, ""))) return;;
    show(c);
/*
 * If possible, we avoid to use FixedFont for printer since it hasn't the
 * right size
 */
    f = gnewfont(lpr, strcmp(fontname, "FixedFont") ? fontname : "Courier New",
		 fontsty, pointsize, 0.0, 1);
    if (!f) {
	/* Should not happen but....*/
	snprintf(msg, LF_FACESIZE + 128,
		 G_("Font %s-%d-%d  not found.\nUsing system fixed font"),
		 strcmp(fontname, "FixedFont") ? fontname : "Courier New",
		 fontsty, pointsize);
	R_ShowMessage(msg);
	f = FixedFont;
    }
    top = devicepixelsy(lpr) / 5;
    left = devicepixelsx(lpr) / 5;
    fh = fontheight(f);
    rr = getheight(lpr) - top;
    cc = getwidth(lpr) - 2*left;
    strncpy(title, GA_gettext(c), 59);
    if (strlen(GA_gettext(c)) > 59) strcpy(&title[56], "...");
    cur = currentcursor();
    setcursor(WatchCursor);

    /* Look for a selection */
    if (p->sel) {
	int len, c1, c2, c3;
	if (p->my0 >= NUMLINES) p->my0 = NUMLINES - 1;
	if (p->my0 < 0) p->my0 = 0;
	len = wcslen(LINE(p->my0));
	if (p->mx0 >= len) p->mx0 = len - 1;
	if (p->mx0 < 0) p->mx0 = 0;
	if (p->my1 >= NUMLINES) p->my1 = NUMLINES - 1;
	if (p->my1 < 0) p->my1 = 0;
	len = wcslen(LINE(p->my1));
	if (p->mx1 >= len) p->mx1 = len - 1;
	if (p->mx1 < 0) p->mx1 = 0;
	c1 = (p->my0 < p->my1);
	c2 = (p->my0 == p->my1);
	c3 = (p->mx0 < p->mx1);
	if (c1 || (c2 && c3)) {
	    x0 = p->mx0; y0 = p->my0;
	    x1 = p->mx1; y1 = p->my1;
	}
	else {
	    x0 = p->mx1; y0 = p->my1;
	    x1 = p->mx0; y1 = p->my0;
	}
    } else {
	x0 = y0 = 0;
	y1 = NUMLINES - 1;
	x1 = wcslen(LINE(y1));
    }

    cl = y0; /* current line */
    clinp = rr;
    cp = 1; /* current page */

    /* s is possible continuation line */
    while ((cl <= y1) || (*s)) {
	if (clinp + fh >= rr) {
	    if (cp > 1) nextpage(lpr);
	    gdrawstr(lpr, f, Black, pt(left, top), title);
	    snprintf(msg, LF_FACESIZE + 128, "Page %d", cp++);
	    gdrawstr(lpr, f, Black,
		     pt(cc - gstrwidth(lpr, f, msg) - 1, top),
		     msg);
	    clinp = top + 2 * fh;
	}
	if (!*s) {
	    if (cl == y0) s = LINE(cl++) + x0;
	    else if (cl < y1) s = LINE(cl++);
	    else if (cl == y1) {
		s = wcsncpy(buf, LINE(cl++), 1023);
		s[min(x1, 1023) + 1] = L'\0';
	    } else break;
	}
	if (!*s) {
	    clinp += fh;
	} else {
	    wchar_t lc = L'\0';
	    for (i = wcslen(s); i > 0; i--) {
		lc = s[i];
		s[i] = L'\0';
		if (gwcswidth(lpr, f, s) < cc) break;
		s[i] = lc;
	    }
	    gdrawwcs(lpr, f, Black, pt(left, clinp), s);
	    clinp += fh;
	    s[i] = lc;
	    s = s + i;
	}
    }

    if (f != FixedFont) del(f);
    del(lpr);
    setcursor(cur);
}

FILE *R_wfopen(const wchar_t *filename, const wchar_t *mode);

void consolesavefile(console c, int pager)
{
    ConsoleData p = getdata(c);

    wchar_t *fn;
    cursor cur;
    FILE *fp;
    int x0, y0, x1, y1, cl;
    wchar_t *s, buf[1024];

    setuserfilterW(L"Text files (*.txt)\0*.txt\0All files (*.*)\0*.*\0\0");
    if(p->sel)
	fn = askfilesaveW(G_("Save selection to"), "lastsave.txt");
    else
	fn = askfilesaveW(G_("Save console contents to"), "lastsave.txt");
    show(c);
    if (fn) {
	fp = R_wfopen(fn, L"wt");
	if (!fp) return;
	cur = currentcursor();
	setcursor(WatchCursor);

	/* Look for a selection */
	if (p->sel) {
	    int len, c1, c2, c3;
	    if (p->my0 >= NUMLINES) p->my0 = NUMLINES - 1;
	    if (p->my0 < 0) p->my0 = 0;
	    len = wcslen(LINE(p->my0));
	    if (p->mx0 >= len) p->mx0 = len - 1;
	    if (p->mx0 < 0) p->mx0 = 0;
	    if (p->my1 >= NUMLINES) p->my1 = NUMLINES - 1;
	    if (p->my1 < 0) p->my1 = 0;
	    len = wcslen(LINE(p->my1));
	    if (p->mx1 >= len) p->mx1 = len - 1;
	    if (p->mx1 < 0) p->mx1 = 0;
	    c1 = (p->my0 < p->my1);
	    c2 = (p->my0 == p->my1);
	    c3 = (p->mx0 < p->mx1);
	    if (c1 || (c2 && c3)) {
		x0 = p->mx0; y0 = p->my0;
		x1 = p->mx1; y1 = p->my1;
	    }
	    else {
		x0 = p->mx1; y0 = p->my1;
		x1 = p->mx0; y1 = p->my0;
	    }
	} else {
	    x0 = y0 = 0;
	    y1 = NUMLINES - 1;
	    x1 = wcslen(LINE(y1));
	}

	for (cl = y0; cl <= y1; cl++) {
	    if (cl == y0) s = LINE(cl) + x0;
	    else if (cl < y1) s = LINE(cl);
	    else if (cl == y1) {
		s = wcsncpy(buf, LINE(cl), 1023);
		s[min(x1, 1023) + 1] = L'\0';
	    } else break;
	    fputws(s, fp); fputc('\n', fp);
	}
	fclose(fp);
	setcursor(cur);
    }
}


console newconsole(char *name, int flags)
{
    console c;
    ConsoleData p;

    p = newconsoledata((consolefn) ? consolefn : FixedFont,
		       consoler, consolec, consolebufb, consolebufl,
		       guiColors,
		       CONSOLE, consolebuffered, consoleblink);
    if (!p) return NULL;
    c = (console) newwindow(name, rect(consolex, consoley, WIDTH, HEIGHT),
			    flags | TrackMouse | VScrollbar | HScrollbar);
    HEIGHT = getheight(c);
    WIDTH  = getwidth(c);
    COLS = WIDTH / FW - 1;
    ROWS = HEIGHT / FH - 1;
    gsetcursor(c, ArrowCursor);
    gchangescrollbar(c, VWINSB, 0, 0, ROWS, 1);
    gchangescrollbar(c, HWINSB, 0, COLS-1, COLS, 1);
    BORDERX = (WIDTH - COLS*FW) / 2;
    BORDERY = (HEIGHT - ROWS*FH) / 2;
    setbackground(c, guiColors[consolebg]);
    BM = newbitmap(WIDTH, HEIGHT, 2);
    if (!c || !BM ) {
	freeConsoleData(p);
	del(c);
	return NULL;
    }
    setdata(c, p);
    sethit(c, console_sbf);
    setresize(c, consoleresize);
    setredraw(c, drawconsole);
    setdel(c, delconsole);
    setkeyaction(c, console_ctrlkeyin);
    setkeydown(c, console_normalkeyin);
    setmousedrag(c, console_mousedrag);
    setmouserepeat(c, console_mouserep);
    setmousedown(c, console_mousedown);
    setim(c, console_im);
    return(c);
}

void  consolehelp()
{
    char s[4096];

    strcpy(s,G_("Scrolling.\n"));
    strcat(s,G_("  Keyboard: PgUp, PgDown, Ctrl+Arrows, Ctrl+Home, Ctrl+End,\n"));
    strcat(s,G_("  Mouse: use the scrollbar(s).\n\n"));
    strcat(s,G_("Editing.\n"));
    strcat(s,G_("  Moving the cursor: \n"));
    strcat(s,G_("     Left arrow or Ctrl+B: move backward one character;\n"));
    strcat(s,G_("     Right arrow or Ctrl+F: move forward one character;\n"));
    strcat(s,G_("     Home or Ctrl+A: go to beginning of line;\n"));
    strcat(s,G_("     End or Ctrl+E: go to end of line;\n"));
    strcat(s,G_("  History: Up and Down Arrows, Ctrl+P, Ctrl+N\n"));
    strcat(s,G_("  Deleting:\n"));
    strcat(s,G_("     Del or Ctrl+D: delete current character or selection;\n"));
    strcat(s,G_("     Backspace: delete preceding character;\n"));
    strcat(s,G_("     Ctrl+Del or Ctrl+K: delete text from current character to end of line.\n"));
    strcat(s,G_("     Ctrl+U: delete all text from current line.\n"));
    strcat(s,G_("  Copy and paste.\n"));
    strcat(s,G_("     Use the mouse (with the left button held down) to mark (select) text.\n"));
    strcat(s,G_("     Use Shift+Del (or Ctrl+C) to copy the marked text to the clipboard and\n"));
    strcat(s,G_("     Shift+Ins (or Ctrl+V or Ctrl+Y) to paste the content of the clipboard (if any)  \n"));
    strcat(s,G_("     to the console, Ctrl+X first copy then paste\n"));
    strcat(s,G_("  Misc:\n"));
    strcat(s,G_("     Ctrl+L: Clear the console.\n"));
    strcat(s,G_("     Ctrl+O or INS: Toggle overwrite mode: initially off.\n"));
    strcat(s,G_("     Ctrl+T: Interchange current char with one to the left.\n"));
    strcat(s,G_("\nNote: Console is updated only when some input is required.\n"));
    strcat(s,G_("  Use Ctrl+W to toggle this feature off/on.\n\n"));
    strcat(s,G_("Use ESC to stop the interpreter.\n\n"));
    strcat(s,G_("TAB starts completion of the current word.\n\n"));
    strcat(s,G_("Standard Windows hotkeys can be used to switch to the\n"));
    strcat(s,G_("graphics device (Ctrl+Tab or Ctrl+F6 in MDI, Alt+Tab in SDI)"));
    askok(s);
}

void consoleclear(control c)
{
    ConsoleData p = getdata(c);

    xbuf l = p->lbuf;
    int oldshift = l->shift;

    l->shift = (l->ns - 1);
    xbufshift(l);
    l->shift = oldshift;
    NEWFV = 0;
    CURROW = 0;
    REDRAW;
}
