/*
 *  R : A Computer Language for Statistical Data Analysis
 *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
 *  Copyright (C) 1998--2022  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/
 */

/* <UTF8>
   Used XTextWidth and XDrawText, so need to use fontsets

   Also needed input context.
*/

/* The version for R 2.1.0 is partly based on patches by
   Ei-ji Nakama <nakama@ki.rim.or.jp> for use with Japanese fonts. */

#define DPRINTS(x) printf(#x "=[%s]\n", x)
#define DPRINTX(x) printf(#x "=%x\n", x)
#define DPRINTD(x) printf(#x "=%d\n", x)

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

#define R_USE_SIGNALS 1
#include <Defn.h>
#include <stdlib.h>
#include <Rinternals.h>
#include <R_ext/Parse.h>  /* parsing is used in handling escape codes */


#ifndef _Xconst
#define _Xconst const
#endif
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#include <X11/Intrinsic.h>

#include <Print.h>
/* For the input handlers of the event loop mechanism: */
#include <R_ext/eventloop.h>
#include <R_ext/RS.h>           /* for CallocCharBuf */
# define USE_FONTSET 1
/* In theory we should do this, but it works less well
# ifdef X_HAVE_UTF8_STRING
#  define HAVE_XUTF8TEXTEXTENTS 1
#  define HAVE_XUTF8DRAWSTRING 1
#  define HAVE_XUTF8DRAWIMAGESTRING 1
# endif */

#ifndef HAVE_KEYSYM
#define KeySym int
#endif

#define DEEvent XEvent

typedef enum { UP, DOWN, LEFT, RIGHT } DE_DIRECTION;

typedef enum {UNKNOWNN, NUMERIC, CHARACTER} CellType;

/* EXPORTS : */
SEXP in_RX11_dataentry(SEXP call, SEXP op, SEXP args, SEXP rho);

/* Global variables needed for the graphics */
static Display *iodisplay = NULL;
static XContext deContext;
static int nView = 0; /* number of open data windows */
static int fdView = -1;

typedef struct {
    Window iowindow;
    GC iogc;
    XFontStruct *font_info;
    SEXP work, names, lens;
    PROTECT_INDEX wpi, npi, lpi;
    int box_w;                       /* width of a box */
    int boxw[100];                   /* widths of cells */
    int box_h;                       /* height of a box */
    int windowWidth;                 /* current width of the window */
    int fullwindowWidth;
    int windowHeight;                /* current height of the window */
    int fullwindowHeight;
    int crow;                        /* current row */
    int ccol;                        /* current column */
    int nwide, nhigh;
    int colmax, colmin, rowmax, rowmin;
    int bwidth;			/* width of the border */
    int hht;			/* height of header  */
    int text_offset;
    int nboxchars;
    int xmaxused, ymaxused;
    char labform[15];  // increased from 6 to pacify gcc 8
    Rboolean isEditor;
    Atom prot;
} destruct, *DEstruct;

/* Local Function Definitions */

static void advancerect(DEstruct, DE_DIRECTION);
static int  CheckControl(DEEvent *);
static int  CheckShift(DEEvent *);
static int  checkquit(int);
static void clearrect(DEstruct);
static void closerect(DEstruct);
static void clearwindow(DEstruct);
static void closewin(DEstruct);
static void copycell(DEstruct);
static void doControl(DEstruct, DEEvent*);
static int  doMouseDown(DEstruct, DEEvent*);
static void doSpreadKey(DEstruct, int, DEEvent*);
static void downlightrect(DEstruct);
static void drawwindow(DEstruct);
static void drawcol(DEstruct, int);
static void drawrow(DEstruct, int);
static void eventloop(DEstruct);
static void find_coords(DEstruct, int, int, int*, int*);
static int  findcell(DEstruct);
static char *GetCharP(DEEvent*);
static KeySym GetKey(DEEvent*);
static void handlechar(DEstruct, char *);
static void highlightrect(DEstruct);
static Rboolean initwin(DEstruct, const char *);
static void jumppage(DEstruct, DE_DIRECTION);
static void jumpwin(DEstruct, int, int);
static void pastecell(DEstruct, int, int);
static void popdownmenu(DEstruct);
static void popupmenu(DEstruct, int, int, int, int);
static void printlabs(DEstruct);
static void printrect(DEstruct, int, int);
static void printstring(DEstruct, const char*, int, int, int, int);
static void printelt(DEstruct, SEXP, int, int, int);
static void RefreshKeyboardMapping(DEEvent*);
static void cell_cursor_init(DEstruct);

/* Functions to hide Xlib calls */
static void bell(void);
static void cleararea(DEstruct, int, int, int, int);
static void copyH(DEstruct, int, int, int);
static void copyarea(DEstruct, int, int, int, int);
static void doConfigure(DEstruct, DEEvent *ioevent);
static void drawrectangle(DEstruct, int, int, int, int, int, int);
static void drawtext(DEstruct, int, int, char*, int);
static void RefreshKeyboardMapping(DEEvent *ioevent);
static void Rsync(DEstruct);
static int textwidth(DEstruct, const char*, int);
static int WhichEvent(DEEvent ioevent);

static void R_ProcessX11Events(void *data);


static const char *get_col_name(DEstruct, int col);
static int  get_col_width(DEstruct, int col);
static CellType get_col_type(DEstruct, int col);
static void calc_pre_edit_pos(DEstruct DE);
static int last_wchar_bytes(char *);
static SEXP ssNewVector(SEXPTYPE, int);
static SEXP ssNA_STRING;


/* only used in the editor */
static Atom _XA_WM_PROTOCOLS = 0;
static Window menuwindow, menupanes[4];
static Rboolean CellModified;
static int box_coords[6];
static int currentexp;                  /* whether an cell is active */
static int ndecimal;                    /* count decimal points */
static int ne;                          /* count exponents */
static int nneg;			/* indicate whether its a negative */
static int clength;                     /* number of characters currently entered */
static int inSpecial;

#define BOOSTED_BUF_SIZE    201
static char buf[BOOSTED_BUF_SIZE];	/* boosted to allow for MBCS */
static char *bufp;
static char copycontents[sizeof(buf)+1] ;

/* The next few and used only for the editor in MBCS locales */
static Status           status;
static XFontSet         font_set = NULL;
static XFontStruct	**fs_list;
static int		font_set_cnt;
static char             fontset_name[]="-*-fixed-medium-r-*-*-*-120-*-*-*-*-*-*";
static XIM		ioim;
static XIMStyle         ioim_style;
static XIMStyles        *ioim_styles;

/*
 * XIM:
 * OverTheSpot XIMPreeditPosition | XIMStatusArea;
 * OffTheSpot  XIMPreeditArea     | XIMStatusArea;
 * Root        XIMPreeditNothing  | XIMStatusNothing;
 */
static XIMStyle preedit_styles[] = {
    XIMPreeditPosition,
    XIMPreeditArea,
    XIMPreeditNothing,
    XIMPreeditNone,
    (XIMStyle)NULL,
};
static XIMStyle status_styles[] = {
    XIMStatusArea,
    XIMStatusNothing,
    XIMStatusNone,
    (XIMStyle)NULL,
};
static XIC ioic = NULL;

#ifndef max
#define max(a, b) (((a)>(b))?(a):(b))
#endif
#ifndef min
#define min(a, b) (((a)<(b))?(a):(b))
#endif
#define BOXW(x) (min(((x<100 && DE->nboxchars==0)?DE->boxw[x]:DE->box_w), DE->fullwindowWidth-DE->boxw[0]-2*DE->bwidth-2))

/*
  Underlying assumptions (for this version R >= 1.8.0)

  The data are stored in a list `work', with unused columns having
  NULL entries.  The names for the list are in `names', which should
  have a name for all displayable columns (up to xmaxused).
  The *used* lengths of the columns are in `lens': this needs only be
  set for non-NULL columns.

  If the list was originally length(0), that should work with
  0 pre-defined cols.  (It used to have 1 pre-defined numeric column.)

  All row and col numbers are 1-based.

  BDR May 2003
 */

/*
   The spreadsheet function returns a list of vectors. The types of
   these vectors can be specified by the user as can their names. It
   the names are specified they are set during initialization. The
   user can change these via a menu interface, they can also change
   the type.

   The vectors are created too long and if they need to be increased
   this is done by using the next higher power of 2. They start 100
   long.  Vectors are initialized to NA when they are created so that
   NA is returned for any cell that was not set by the user.  We use
   a special type of NA to distinguish this from user-supplied NAs.

   In Macintosh we needed to call the main event loop to get
   events. This ensures that the spreadsheet interacts well with the
   other windows. Under X windows we let the window manager handle
   those sorts of details.

 */

static char *menu_label[] =
{
    " Real",
    " Character",
    "Change Name ",
};

/*
   ssNewVector is just an interface to allocVector but it lets us
   set the fields to NA. We need to have a special NA for reals and
   strings so that we can differentiate between uninitialized elements
   in the vectors and user supplied NA's; hence ssNA_STRING
 */

static SEXP ssNewVector(SEXPTYPE type, int vlen)
{
    SEXP tvec;
    int j;

    tvec = allocVector(type, vlen);
    for (j = 0; j < vlen; j++)
	if (type == REALSXP)
	    REAL(tvec)[j] = NA_REAL;
	else if (type == STRSXP)
	    SET_STRING_ELT(tvec, j, ssNA_STRING);
    return (tvec);
}

static void closewin_cend(void *data)
{
    DEstruct DE = (DEstruct) data;
    closewin(DE);
}

SEXP in_RX11_dataentry(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP colmodes, tnames, tvec, tvec2, work2;
    SEXPTYPE type;
    int i, j, cnt, len, nprotect;
    RCNTXT cntxt;
    char clab[25];
    char *title = "R Data Editor";
    destruct DE1;
    DEstruct DE = &DE1;

    nprotect = 0;/* count the PROTECT()s */
    PROTECT_WITH_INDEX(DE->work = duplicate(CAR(args)), &DE->wpi); nprotect++;
    colmodes = CADR(args);
    tnames = getAttrib(DE->work, R_NamesSymbol);

    if (TYPEOF(DE->work) != VECSXP || TYPEOF(colmodes) != VECSXP)
	errorcall(call, "invalid argument");

    /* initialize the constants */

    bufp = buf;
    ne = 0;
    currentexp = 0;
    nneg = 0;
    ndecimal = 0;
    clength = 0;
    inSpecial = 0;
    DE->ccol = 1;
    DE->crow = 1;
    DE->colmin = 1;
    DE->rowmin = 1;
    PROTECT(ssNA_STRING = duplicate(NA_STRING));
    nprotect++;
    DE->bwidth = 5;
    DE->hht = 30;
    DE->isEditor = TRUE;

    /* setup work, names, lens  */
    DE->xmaxused = length(DE->work); DE->ymaxused = 0;
    PROTECT_WITH_INDEX(DE->lens = allocVector(INTSXP, DE->xmaxused), &DE->lpi);
    nprotect++;

    if (isNull(tnames)) {
	PROTECT_WITH_INDEX(DE->names = allocVector(STRSXP, DE->xmaxused),
			   &DE->npi);
	for(i = 0; i < DE->xmaxused; i++) {
	    sprintf(clab, "var%d", i);
	    SET_STRING_ELT(DE->names, i, mkChar(clab));
	}
    } else
	PROTECT_WITH_INDEX(DE->names = duplicate(tnames), &DE->npi);
    nprotect++;
    for (i = 0; i < DE->xmaxused; i++) {
	int len = LENGTH(VECTOR_ELT(DE->work, i));
	INTEGER(DE->lens)[i] = len;
	DE->ymaxused = max(len, DE->ymaxused);
	type = TYPEOF(VECTOR_ELT(DE->work, i));
	if (LENGTH(colmodes) > 0 && !isNull(VECTOR_ELT(colmodes, i)))
	    type = str2type(CHAR(STRING_ELT(VECTOR_ELT(colmodes, i), 0)));
	if (type != STRSXP) type = REALSXP;
	if (isNull(VECTOR_ELT(DE->work, i))) {
	    if (type == NILSXP) type = REALSXP;
	    SET_VECTOR_ELT(DE->work, i, ssNewVector(type, 100));
	} else if (!isVector(VECTOR_ELT(DE->work, i)))
	    errorcall(call, "invalid type for value");
	else {
	    if (TYPEOF(VECTOR_ELT(DE->work, i)) != type)
		SET_VECTOR_ELT(DE->work, i,
			       coerceVector(VECTOR_ELT(DE->work, i), type));
	}
    }


    /* start up the window, more initializing in here */
    if (initwin(DE, title))
	errorcall(call, "unable to start data editor");

    /* set up a context which will close the window if there is an error */
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
		 R_NilValue, R_NilValue);
    cntxt.cend = &closewin_cend;
    cntxt.cenddata = (void *) DE;

    highlightrect(DE);

    cell_cursor_init(DE);

    eventloop(DE);

    endcontext(&cntxt);
    closewin(DE);
    if(nView == 0) {
	if(fdView >= 0) { /* might be open after viewers, but unlikely */
	    removeInputHandler(&R_InputHandlers,
			       getInputHandler(R_InputHandlers,fdView));
	    fdView = -1;
	}
	if(font_set) {
	    XFreeFontSet(iodisplay, font_set);
	    font_set = NULL;
	}
	XCloseDisplay(iodisplay);
	iodisplay = NULL;
    }

    /* drop out unused columns */
    for(i = 0, cnt = 0; i < DE->xmaxused; i++)
	if(!isNull(VECTOR_ELT(DE->work, i))) cnt++;
    if (cnt < DE->xmaxused) {
	PROTECT(work2 = allocVector(VECSXP, cnt)); nprotect++;
	for(i = 0, j = 0; i < DE->xmaxused; i++) {
	    if(!isNull(VECTOR_ELT(DE->work, i))) {
		SET_VECTOR_ELT(work2, j, VECTOR_ELT(DE->work, i));
		INTEGER(DE->lens)[j] = INTEGER(DE->lens)[i];
		SET_STRING_ELT(DE->names, j, STRING_ELT(DE->names, i));
		j++;
	    }
	}
	REPROTECT(DE->names = lengthgets(DE->names, cnt), DE->npi);
    } else work2 = DE->work;

    for (i = 0; i < LENGTH(work2); i++) {
	len = INTEGER(DE->lens)[i];
	tvec = VECTOR_ELT(work2, i);
	if (LENGTH(tvec) != len) {
	    tvec2 = ssNewVector(TYPEOF(tvec), len);
	    for (j = 0; j < len; j++) {
		if (TYPEOF(tvec) == REALSXP) {
			REAL(tvec2)[j] = REAL(tvec)[j];
		} else if (TYPEOF(tvec) == STRSXP) {
		    if (STRING_ELT(tvec, j) != ssNA_STRING)
			SET_STRING_ELT(tvec2, j, STRING_ELT(tvec, j));
		    else
			SET_STRING_ELT(tvec2, j, NA_STRING);
		} else
		    error("dataentry: internal memory problem");
	    }
	    SET_VECTOR_ELT(work2, i, tvec2);
	}
    }

    setAttrib(work2, R_NamesSymbol, DE->names);
    UNPROTECT(nprotect);
    return work2;
}

static void dv_closewin_cend(void *data)
{
    DEstruct DE = (DEstruct) data;
    R_ReleaseObject(DE->lens);
    R_ReleaseObject(DE->work);
    closewin(DE);
    free(DE);
    nView--;
}

SEXP in_R_X11_dataviewer(SEXP call, SEXP op, SEXP args, SEXP rho)
{
    SEXP stitle;
    SEXPTYPE type;
    int i, nprotect;
    RCNTXT cntxt;
    // FIXME: this should be checked
    DEstruct DE = (DEstruct) malloc(sizeof(destruct));
    if(!DE) error("allocation failed in in_R_X11_dataviewer");

    nView++;

    nprotect = 0;/* count the PROTECT()s */
    DE->work = CAR(args);
    DE->names = getAttrib(DE->work, R_NamesSymbol);

    if (TYPEOF(DE->work) != VECSXP)
	errorcall(call, "invalid argument");
    stitle = CADR(args);
    if (!isString(stitle) || LENGTH(stitle) != 1)
	errorcall(call, "invalid argument");

    /* initialize the constants */

    bufp = buf;
    ne = 0;
    currentexp = 0;
    nneg = 0;
    ndecimal = 0;
    clength = 0;
    inSpecial = 0;
    DE->ccol = 1;
    DE->crow = 1;
    DE->colmin = 1;
    DE->rowmin = 1;
    DE->bwidth = 5;
    DE->hht = 10;
    DE->isEditor = FALSE;

    /* setup work, names, lens  */
    DE->xmaxused = length(DE->work); DE->ymaxused = 0;
    PROTECT_WITH_INDEX(DE->lens = allocVector(INTSXP, DE->xmaxused), &DE->lpi);
    nprotect++;

    for (i = 0; i < DE->xmaxused; i++) {
	int len = LENGTH(VECTOR_ELT(DE->work, i));
	INTEGER(DE->lens)[i] = len;
	DE->ymaxused = max(len, DE->ymaxused);
	type = TYPEOF(VECTOR_ELT(DE->work, i));
	if (type != STRSXP && type != REALSXP)
	    errorcall(call, "invalid argument");
    }


    /* start up the window, more initializing in here */
    if (initwin(DE, CHAR(STRING_ELT(stitle, 0))))
	errorcall(call, "unable to start data viewer");

    /* set up a context which will close the window if there is an error */
    begincontext(&cntxt, CTXT_CCODE, R_NilValue, R_BaseEnv, R_BaseEnv,
		 R_NilValue, R_NilValue);
    cntxt.cend = &dv_closewin_cend;
    cntxt.cenddata = (void *) DE;

    highlightrect(DE);

    cell_cursor_init(DE);

    if(fdView < 0) {
	fdView = ConnectionNumber(iodisplay);
	addInputHandler(R_InputHandlers, fdView,
			R_ProcessX11Events, XActivity);
    }

    drawwindow(DE);

    R_PreserveObject(DE->work); /* also preserves names */
    R_PreserveObject(DE->lens);
    UNPROTECT(nprotect);
    return R_NilValue;
}

/* Window Drawing Routines */

static void setcellwidths(DEstruct DE)
{
    int i, w, dw;

    DE->windowWidth = w = 2*DE->bwidth + DE->boxw[0] + BOXW(DE->colmin);
    DE->nwide = 2;
    for (i = 2; i < 100; i++) { /* 100 on-screen columns cannot occur */
	dw = BOXW(i + DE->colmin - 1);
	if((w += dw) > DE->fullwindowWidth ||
	   (!DE->isEditor && i > DE->xmaxused - DE->colmin + 1)) {
	    DE->nwide = i;
	    DE->windowWidth = w - dw;
	    break;
	}
    }
}

static void drawwindow(DEstruct DE)
{
    int i, st;
    XWindowAttributes attribs;

    /* if there is an active cell enter the data in it */
    /*
     * case colname input Expose not use.
     * closerect();
     */

    /* now set up the window with the new dimensions */
    XGetWindowAttributes(iodisplay, DE->iowindow, &attribs);
    DE->bwidth = attribs.border_width;
    DE->fullwindowWidth = attribs.width;
    DE->fullwindowHeight = attribs.height;
    setcellwidths(DE);
    DE->nhigh = (DE->fullwindowHeight - 2 * DE->bwidth - DE->hht) / DE->box_h;
    DE->windowHeight = DE->nhigh * DE->box_h + 2 * DE->bwidth;

    clearwindow(DE);


    for (i = 1; i < DE->nhigh; i++)
	drawrectangle(DE, 0, DE->hht + i * DE->box_h, DE->boxw[0], DE->box_h,
		      1, 1);
     /* so row 0 and col 0 are reserved for labels */
    DE->colmax = DE->colmin + (DE->nwide - 2);
    DE->rowmax = DE->rowmin + (DE->nhigh - 2);
    printlabs(DE);
    for (i = DE->colmin; i <= DE->colmax; i++) drawcol(DE, i);

    if(DE->isEditor) {
	/* draw the quit etc boxes */

	i = textwidth(DE, "Quit", 4);
	box_coords[0] = st = DE->fullwindowWidth - 6 - DE->bwidth;
	box_coords[1] = st - i;
	drawrectangle(DE, st - i, 3, i + 4, DE->hht - 6, 1, 1);
	drawtext(DE, st + 2 - i, DE->hht - 7, "Quit", 4);

	box_coords[4] = st = st - 5*i;
	i = textwidth(DE, "Paste", 5);
	box_coords[5] = st - i;
	drawrectangle(DE, st - i, 3, i + 4, DE->hht - 6, 1, 1);
	drawtext(DE, st + 2 - i, DE->hht - 7, "Paste", 5);

	box_coords[2] = st = st - 2*i;
	i = textwidth(DE, "Copy", 4);
	box_coords[3] = st - i;
	drawrectangle(DE, st - i, 3, i + 4, DE->hht - 6, 1, 1);
	drawtext(DE, st + 2 - i, DE->hht - 7, "Copy", 4);
    }

    highlightrect(DE);

    Rsync(DE);

}

static void doHscroll(DEstruct DE, int oldcol)
{
    int i, dw;
    int oldnwide = DE->nwide, oldwindowWidth = DE->windowWidth;

    /* horizontal re-position */
    setcellwidths(DE);
    DE->colmax = DE->colmin + (DE->nwide - 2);
    if (oldcol < DE->colmin) { /* drop oldcol...colmin - 1 */
	dw = DE->boxw[0];
	for (i = oldcol; i < DE->colmin; i++) dw += BOXW(i);
	copyH(DE, dw, DE->boxw[0], oldwindowWidth - dw + 1);
	dw = oldwindowWidth - BOXW(oldcol) + 1;
	cleararea(DE, dw, DE->hht, DE->fullwindowWidth-dw,
		  DE->fullwindowHeight);
	/* oldnwide includes the row labels */
	for (i = oldcol+oldnwide-1; i <= DE->colmax; i++) drawcol(DE, i);
    } else {
	/* move one or more cols left */
	dw = BOXW(DE->colmin);
	copyH(DE, DE->boxw[0], DE->boxw[0] + dw, DE->windowWidth - dw + 1);
	dw = DE->windowWidth + 1;
	cleararea(DE, dw, DE->hht, DE->fullwindowWidth-dw,
		  DE->fullwindowHeight);
	drawcol(DE, DE->colmin);
    }

    highlightrect(DE);
    cell_cursor_init(DE);

    Rsync(DE);
}

/* find_coords finds the coordinates of the upper left corner of the
   given cell on the screen: row and col are on-screen coords */

static void find_coords(DEstruct DE,
			int row, int col, int *xcoord, int *ycoord)
{
    int i, w;
    w = DE->bwidth;
    if (col > 0) w += DE->boxw[0];
    for(i = 1; i < col; i ++) w += BOXW(i + DE->colmin - 1);
    *xcoord = w;
    *ycoord = DE->bwidth + DE->hht + DE->box_h * row;
}

/* draw the window with the top left box at column wcol and row wrow */

static void jumpwin(DEstruct DE, int wcol, int wrow)
{
    if (wcol < 0 || wrow < 0) {
	bell();
	return;
    }
    closerect(DE);
    if (DE->colmin != wcol || DE->rowmin != wrow) {
	DE->colmin = wcol;
	DE->rowmin = wrow;
	closerect(DE);
	drawwindow(DE);
    } else highlightrect(DE);
}

static void advancerect(DEstruct DE, DE_DIRECTION which)
{

    /* if we are in the header, changing a name then only down is
       allowed */
    if (DE->crow < 1 && which != DOWN) {
	bell();
	return;
    }

    closerect(DE);

    switch (which) {
    case UP:
	if (DE->crow == 1) {
	    if (DE->rowmin == 1)
		bell();
	    else
		jumppage(DE, UP);
	} else
	    DE->crow--;
	break;
    case DOWN:
	if (!DE->isEditor && DE->crow+DE->rowmin > DE->ymaxused) {
	    bell();
	    break;
	}
	if (DE->crow == (DE->nhigh - 1))
	    jumppage(DE, DOWN);
	else
	    DE->crow++;
	break;
    case RIGHT:
	if (!DE->isEditor && DE->ccol+DE->colmin > DE->xmaxused) {
	    bell();
	    break;
	}
	if (DE->ccol == (DE->nwide - 1))
	    jumppage(DE, RIGHT);
	else
	    DE->ccol++;
	break;
    case LEFT:
	if (DE->ccol == 1) {
	    if (DE->colmin == 1)
		bell();
	    else
		jumppage(DE, LEFT);
	} else
	    DE->ccol--;
	break;
    default:
	UNIMPLEMENTED("advancerect");
    }

    highlightrect(DE);

    cell_cursor_init(DE);
}

static void cell_cursor_init(DEstruct DE)
{
    int i, whichrow = DE->crow + DE->rowmin - 1,
	whichcol = DE->ccol + DE->colmin -1;
    SEXP tmp;

    memset(buf,0,sizeof(buf));

    if (DE->crow == 0 ){
	strncpy(buf,
		get_col_name(DE, whichcol),
		BOOSTED_BUF_SIZE-1);
    } else {
	if (length(DE->work) >= whichcol) {
	    tmp = VECTOR_ELT(DE->work, whichcol - 1);
	    if (tmp != R_NilValue &&
		(i = whichrow - 1) < LENGTH(tmp) ) {
		PrintDefaults();
		if (TYPEOF(tmp) == REALSXP) {
		    strncpy(buf, EncodeElement(tmp, i, 0, '.'),
			    BOOSTED_BUF_SIZE-1);
		} else if (TYPEOF(tmp) == STRSXP) {
		    if (STRING_ELT(tmp, i) != ssNA_STRING)
			strncpy(buf, EncodeElement(tmp, i, 0, '.'),
				BOOSTED_BUF_SIZE-1);
		}
	    }
	}
    }
    buf[BOOSTED_BUF_SIZE-1] = '\0';
    clength = (int) strlen(buf);
    bufp = buf + clength;
}

static const char *get_col_name(DEstruct DE, int col)
{
    static char clab[25];
    int nwrote;
    if (col <= DE->xmaxused) {
	/* don't use NA labels */
	SEXP tmp = STRING_ELT(DE->names, col - 1);
	if(tmp != NA_STRING) return(CHAR(tmp));
    }
    nwrote = snprintf(clab, 25, "var%d", col);
    if (nwrote >= 25)
	error("get_col_name: column number too big to stringify");
    return (const char *)clab;
}

static int get_col_width(DEstruct DE, int col)
{
    int i, w = 0, w1;
    const char *strp;
    SEXP tmp, lab;

    if (DE->nboxchars > 0) return DE->box_w;
    if (col <= DE->xmaxused) {
	tmp = VECTOR_ELT(DE->work, col - 1);
	if (isNull(tmp)) return DE->box_w;
	/* don't use NA labels */
	lab = STRING_ELT(DE->names, col - 1);
	if(lab != NA_STRING) strp = CHAR(lab); else strp = "var12";
	PrintDefaults();

	w = textwidth(DE, strp, (int) strlen(strp));
	for (i = 0; i < INTEGER(DE->lens)[col - 1]; i++) {
	    strp = EncodeElement(tmp, i, 0, '.');
	    w1 = textwidth(DE, strp, (int) strlen(strp));
	    if (w1 > w) w = w1;
	}
	if(w < 0.5*DE->box_w) w = (int) (0.5*DE->box_w);
	if(w < 0.8*DE->box_w) w+= (int) (0.1*DE->box_w);
	if(w > 600) w = 600;
	return w+8;
    }
    return DE->box_w;
}

static CellType get_col_type(DEstruct DE, int col)
{
    SEXP tmp;
    CellType res = UNKNOWNN;

    if (col <= DE->xmaxused) {
	tmp = VECTOR_ELT(DE->work, col - 1);
	if(TYPEOF(tmp) == REALSXP) res = NUMERIC;
	if(TYPEOF(tmp) == STRSXP) res = CHARACTER;
    }
    return res;
}


/* whichcol is absolute col no, col is position on screen */
static void drawcol(DEstruct DE, int whichcol)
{
    int i, src_x, src_y, len, col = whichcol - DE->colmin + 1,
	bw = BOXW(whichcol);
    const char *clab;
    SEXP tmp;

    find_coords(DE, 0, col, &src_x, &src_y);
    cleararea(DE, src_x, src_y, bw, DE->windowHeight);
    for (i = 0; i < DE->nhigh; i++)
	drawrectangle(DE, src_x, DE->hht + i * DE->box_h, bw, DE->box_h, 1, 1);

    /* now fill it in if it is active */
    clab = get_col_name(DE, whichcol);
    printstring(DE, clab, (int) strlen(clab), 0, col, 0);

   if (DE->xmaxused >= whichcol) {
	tmp = VECTOR_ELT(DE->work, whichcol - 1);
	if (!isNull(tmp)) {
	    len = min(DE->rowmax, INTEGER(DE->lens)[whichcol - 1]);
	    for (i = (DE->rowmin - 1); i < len; i++)
		printelt(DE, tmp, i, i - DE->rowmin + 2, col);
	}
    }
    Rsync(DE);
}


/* whichrow is absolute row no */
static void drawrow(DEstruct DE, int whichrow)
{
    int i, src_x, src_y, row = whichrow - DE->rowmin + 1, w;
    char rlab[15];
    SEXP tvec;

    find_coords(DE, row, 0, &src_x, &src_y);
    cleararea(DE, src_x, src_y, DE->windowWidth, DE->box_h);
    drawrectangle(DE, src_x, src_y, DE->boxw[0], DE->box_h, 1, 1);

    sprintf(rlab, DE->labform, whichrow);
    printstring(DE, rlab, (int)strlen(rlab), row, 0, 0);

    w = DE->bwidth + DE->boxw[0];
    for (i = DE->colmin; i <= DE->colmax; i++) {
	drawrectangle(DE, w, src_y, BOXW(i), DE->box_h, 1, 1);
	w += BOXW(i);
    }

    for (i = DE->colmin; i <= DE->colmax; i++) {
	if (i > DE->xmaxused) break;
	if (!isNull(tvec = VECTOR_ELT(DE->work, i - 1)))
	    if (whichrow <= INTEGER(DE->lens)[i - 1])
		printelt(DE, tvec, whichrow - 1, row, i - DE->colmin + 1);
    }

    Rsync(DE);
}

/* printelt: print the correct value from vector[vrow] into the
   spreadsheet in row ssrow and col sscol */

/* WARNING: This has no check that you're not beyond the end of the
   vector. Caller must check. */

static void printelt(DEstruct DE, SEXP invec, int vrow, int ssrow, int sscol)
{
    const char *strp;
    PrintDefaults();
    if (TYPEOF(invec) == REALSXP) {
	strp = EncodeElement(invec, vrow, 0, '.');
	printstring(DE ,strp, (int) strlen(strp), ssrow, sscol, 0);
    }
    else if (TYPEOF(invec) == STRSXP) {
	if (STRING_ELT(invec, vrow) != ssNA_STRING) {
	    strp = EncodeElement(invec, vrow, 0, '.');
	    printstring(DE ,strp, (int) strlen(strp), ssrow, sscol, 0);
	}
    }
    else
	error("dataentry: internal memory error");
}


static void drawelt(DEstruct DE, int whichrow, int whichcol)
{
    int i;
    const char *clab;
    SEXP tmp;

    if (whichrow == 0) {
	clab = get_col_name(DE, whichcol + DE->colmin - 1);
	printstring(DE ,clab, (int) strlen(clab), 0, whichcol, 0);
    } else {
	if (DE->xmaxused >= whichcol + DE->colmin - 1) {
	    tmp = VECTOR_ELT(DE->work, whichcol + DE->colmin - 2);
	    if (!isNull(tmp) && (i = DE->rowmin + whichrow - 2) <
		INTEGER(DE->lens)[whichcol + DE->colmin - 2] )
		printelt(DE, tmp, i, whichrow, whichcol);
	} else
	    printstring(DE, "", 0, whichrow,  whichcol, 0);
    }

    Rsync(DE);
}

static void jumppage(DEstruct DE, DE_DIRECTION dir)
{
    int i, w, oldcol, wcol;

    switch (dir) {
    case UP:
	DE->rowmin--;
	DE->rowmax--;
	copyarea(DE, 0, DE->hht + DE->box_h, 0, DE->hht + 2 * DE->box_h);
	drawrow(DE, DE->rowmin);
	break;
    case DOWN:
	if (DE->rowmax >= 65535) return;
	DE->rowmin++;
	DE->rowmax++;
	copyarea(DE, 0, DE->hht + 2 * DE->box_h, 0, DE->hht + DE->box_h);
	drawrow(DE, DE->rowmax);
	break;
    case LEFT:
	DE->colmin--;
	doHscroll(DE, DE->colmin+1);
	break;
    case RIGHT:
	oldcol = DE->colmin;
	wcol = DE->colmin + DE->ccol + 1; /* column to be selected */
	/* There may not be room to fit the next column in */
	w = DE->fullwindowWidth - DE->boxw[0] - BOXW(DE->colmax + 1);
	for (i = DE->colmax; i >= oldcol; i--) {
	    w -= BOXW(i);
	    if(w < 0) {
		DE->colmin = i + 1;
		break;
	    }
	}
	DE->ccol = wcol - DE->colmin;
	doHscroll(DE, oldcol);
	break;
    }
}
/* draw a rectangle, used to highlight/downlight the current box */

static void printrect(DEstruct DE, int lwd, int fore)
{
    int x, y;
    find_coords(DE, DE->crow, DE->ccol, &x, &y);
    drawrectangle(DE, x + lwd - 1, y + lwd - 1,
		  BOXW(DE->ccol+DE->colmin-1) - lwd + 1,
		  DE->box_h - lwd + 1, lwd, fore);
    Rsync(DE);
}

static void downlightrect(DEstruct DE)
{
    printrect(DE, 2, 0);
    printrect(DE, 1, 1);
}

static void highlightrect(DEstruct DE)
{
    printrect(DE, 2, 1);
}


static Rboolean getccol(DEstruct DE)
{
    SEXP tmp, tmp2;
    int i, len, newlen, wcol, wrow;
    SEXPTYPE type;
    char clab[25];
    Rboolean newcol = FALSE;

    wcol = DE->ccol + DE->colmin - 1;
    wrow = DE->crow + DE->rowmin - 1;
    if (wcol > DE->xmaxused) {
	/* extend work, names and lens */
	REPROTECT(DE->work = lengthgets(DE->work, wcol), DE->wpi);
	REPROTECT(DE->names = lengthgets(DE->names, wcol), DE->npi);
	for (i = DE->xmaxused; i < wcol; i++) {
	    sprintf(clab, "var%d", i + 1);
	    SET_STRING_ELT(DE->names, i, mkChar(clab));
	}
	REPROTECT(DE->lens = lengthgets(DE->lens, wcol), DE->lpi);
	DE->xmaxused = wcol;
    }
    if (isNull(VECTOR_ELT(DE->work, wcol - 1))) {
	newcol = TRUE;
	SET_VECTOR_ELT(DE->work, wcol - 1,
		       ssNewVector(REALSXP, max(100, wrow)));
	INTEGER(DE->lens)[wcol - 1] = 0;
    }
    if (!isVector(tmp = VECTOR_ELT(DE->work, wcol - 1)))
	error("internal type error in dataentry");
    len = INTEGER(DE->lens)[wcol - 1];
    type = TYPEOF(tmp);
    if (len < wrow) {
	for (newlen = max(len * 2, 10) ; newlen < wrow ; newlen *= 2)
	    ;
	tmp2 = ssNewVector(type, newlen);
	for (i = 0; i < len; i++)
	    if (type == REALSXP)
		REAL(tmp2)[i] = REAL(tmp)[i];
	    else if (type == STRSXP)
		SET_STRING_ELT(tmp2, i, STRING_ELT(tmp, i));
	    else
		error("internal type error in dataentry");
	SET_VECTOR_ELT(DE->work, wcol - 1, tmp2);
    }
    return newcol;
}

static SEXP processEscapes(SEXP x)
{
    SEXP newval, pattern, replacement, expr;
    ParseStatus status;

    /* We process escape sequences in a scalar string by escaping
       unescaped quotes, then quoting the whole thing and parsing it.  This
       is supposed to be equivalent to the R code

       newval <- gsub(perl=TRUE, "(?<!\\\\)((\\\\\\\\)*)\"", "\\1\\\\\"", x)
       newval <- sub('(^.*$)', '"\1"', newval)
       newval <- eval(parse(text=newval))

       We do it this way to avoid extracting the escape handling
       code from the parser.  We need it in C code because this may be executed
       numerous times from C in dataentry.c */

    PROTECT( pattern = mkString("(?<!\\\\)((\\\\\\\\)*)\"") );
    PROTECT( replacement = mkString("\\1\\\\\"") );
    SEXP s_gsub = install("gsub");
    PROTECT( expr = lang5(s_gsub, ScalarLogical(1), pattern, replacement, x) );
    SET_TAG( CDR(expr), install("perl") );

    PROTECT( newval = eval(expr, R_BaseEnv) );
    PROTECT( pattern = mkString("(^.*$)") );
    PROTECT( replacement = mkString("\"\\1\"") );
    PROTECT( expr = lang4(install("sub"), pattern, replacement, newval) );
    PROTECT( newval = eval(expr, R_BaseEnv) );
    PROTECT( expr = R_ParseVector( newval, 1, &status, R_NilValue) );

    /* We only handle the first entry. If this were available more generally,
       we'd probably want to loop over all of expr */

    if (status == PARSE_OK && length(expr))
	PROTECT( newval = eval(VECTOR_ELT(expr, 0), R_BaseEnv) );
    else
	PROTECT( newval = R_NilValue );  /* protect just so the count doesn't change */
    UNPROTECT(10);
    return newval;
}

/* close up the entry to a cell, put the value that has been entered
   into the correct place and as the correct type */

static void closerect(DEstruct DE)
{
    SEXP cvec;
    int i, wcol = DE->ccol + DE->colmin - 1,
	wrow = DE->rowmin + DE->crow - 1, wrow0;
    char clab[25];
    Rboolean newcol;

    *bufp = '\0';

    /* first check to see if anything has been entered */
    if (CellModified) {
	if (DE->crow == 0) {
	    if (clength != 0) {
		/* then we are entering a new column name */
		if (DE->xmaxused < wcol) {
		    /* extend work, names and lens */
		    REPROTECT(DE->work = lengthgets(DE->work, wcol), DE->wpi);
		    REPROTECT(DE->names = lengthgets(DE->names, wcol),
			      DE->npi);
		    for (i = DE->xmaxused; i < wcol - 1; i++) {
			sprintf(clab, "var%d", i + 1);
			SET_STRING_ELT(DE->names, i, mkChar(clab));
		    }
		    REPROTECT(DE->lens = lengthgets(DE->lens, wcol), DE->lpi);
		    DE->xmaxused = wcol;
		}
		SET_STRING_ELT(DE->names, wcol - 1, mkChar(buf));
		printstring(DE ,buf, (int) strlen(buf), 0, wcol, 0);
	    } else {
		sprintf(buf, "var%d", DE->ccol);
		printstring(DE ,buf, (int) strlen(buf), 0, wcol, 0);
	    }
	} else {
	    newcol = getccol(DE);
	    cvec = VECTOR_ELT(DE->work, wcol - 1);
	    wrow0 = INTEGER(DE->lens)[wcol - 1];
	    if (wrow > wrow0) INTEGER(DE->lens)[wcol - 1] = wrow;
	    DE->ymaxused = max(DE->ymaxused, wrow);
	    if (clength != 0) {
		/* do it this way to ensure NA, Inf, ...  can get set */
		char *endp;
		double new = R_strtod(buf, &endp);
		Rboolean warn = !isBlankString(endp);
		if (TYPEOF(cvec) == STRSXP) {
		    SEXP newval;
		    PROTECT( newval = mkString(buf) );
		    PROTECT( newval = processEscapes(newval) );
		    if (TYPEOF(newval) == STRSXP && length(newval) == 1)
			SET_STRING_ELT(cvec, wrow - 1, STRING_ELT(newval, 0));
		    else
			warning("dataentry: parse error on string");
		    UNPROTECT(2);
		} else
		    REAL(cvec)[wrow - 1] = new;
		if (newcol && warn) {
		    /* change mode to character */
		    SEXP tmp = coerceVector(cvec, STRSXP);
		    PROTECT(tmp);
		    SET_STRING_ELT(tmp, wrow - 1, mkChar(buf));
		    SET_VECTOR_ELT(DE->work, wcol - 1, tmp);
		    UNPROTECT(1);
		}
	    } else {
		if (TYPEOF(cvec) == STRSXP)
		    SET_STRING_ELT(cvec, wrow - 1, NA_STRING);
		else
		    REAL(cvec)[wrow - 1] = NA_REAL;
	    }
	    drawelt(DE, DE->crow, DE->ccol); /* to get the cell scrolling right */
	    if(wrow > wrow0) drawcol(DE, wcol); /* to fill in NAs */
	}
    }
    CellModified = FALSE;

    downlightrect(DE);

    ndecimal = 0;
    nneg = 0;
    ne = 0;
    currentexp = 0;
    clength = 0;
    inSpecial = 0;
    bufp = buf;
}

/* print a null terminated string, check to see if it is longer than
   the print area and print it, left adjusted if necessary; clear the
   area of previous text; */

/* This version will only display 200 chars, but the maximum col width
   will not allow that many */
static void printstring(DEstruct DE, const char *ibuf, int buflen, int row,
			int col, int left)
{
    int i, x_pos, y_pos, bw, bufw;
    char pbuf[BOOSTED_BUF_SIZE];
    int wcsbufw,j;
    wchar_t wcspbuf[BOOSTED_BUF_SIZE], *wcspc = wcspbuf;
    wchar_t wcs[BOOSTED_BUF_SIZE];
    char    s[BOOSTED_BUF_SIZE];
    wchar_t *w_p;
    char    *p;
    int cnt;

    find_coords(DE, row, col, &x_pos, &y_pos);
    if (col == 0) bw = DE->boxw[0]; else bw = BOXW(col+DE->colmin-1);
    cleararea(DE, x_pos + 2, y_pos + 2, bw - 3, DE->box_h - 3);
    bufw = (buflen > BOOSTED_BUF_SIZE-1) ? BOOSTED_BUF_SIZE-1 : buflen;
    strncpy(pbuf, ibuf, bufw);
    pbuf[bufw] = '\0';

    p = pbuf;
    wcsbufw = (int) mbsrtowcs(wcspbuf, (const char **)&p, bufw, NULL);
    wcspbuf[wcsbufw]=L'\0';
    if(left) {
	for (i = wcsbufw; i > 1; i--) {
	    for(j=0;*(wcspc+j)!=L'\0';j++)wcs[j]=*(wcspc+j);
	    wcs[j]=L'\0';
	    w_p=wcs;
	    cnt = (int) wcsrtombs(s,(const wchar_t **)&w_p,sizeof(s)-1,NULL);
	    s[cnt]='\0';
	    if (textwidth(DE, s, (int) strlen(s)) < (bw - DE->text_offset)) break;
	    *(++wcspc) = L'<';
	}
    } else {
	for (i = wcsbufw; i > 1; i--) {
	    for(j=0;*(wcspc+j)!=L'\0';j++)wcs[j]=*(wcspc+j);
	    wcs[j]=L'\0';
	    w_p=wcs;
	    cnt = (int) wcsrtombs(s,(const wchar_t **)&w_p,sizeof(s)-1,NULL);
	    s[cnt]='\0';
	    if (textwidth(DE, s, (int) strlen(s)) < (bw - DE->text_offset)) break;
	    *(wcspbuf + i - 2) = L'>';
	    *(wcspbuf + i - 1) = L'\0';
	}
    }
    for(j=0;*(wcspc+j)!=L'\0';j++) wcs[j]=*(wcspc+j);
    wcs[j]=L'\0';
    w_p=wcs;
    cnt = (int) wcsrtombs(s,(const wchar_t **)&w_p,sizeof(s)-1,NULL);

    drawtext(DE, x_pos + DE->text_offset, y_pos + DE->box_h - DE->text_offset,
	     s, cnt);

    Rsync(DE);
}

static void clearrect(DEstruct DE)
{
    int x_pos, y_pos;

    find_coords(DE, DE->crow, DE->ccol, &x_pos, &y_pos);
    cleararea(DE, x_pos, y_pos, BOXW(DE->ccol+DE->colmin-1), DE->box_h);
    Rsync(DE);
}

/* handlechar has to be able to parse decimal numbers and strings,
   depending on the current column type, only printing characters
   should get this far */

/* --- Not true! E.g. ESC ends up in here... */

#include <rlocale.h>

/* <FIXME> This is not correct for stateful MBCSs, but that's hard to
   do as we get a char at a time */
static void handlechar(DEstruct DE, char *text)
{
    int c = text[0], j;
    wchar_t wcs[BOOSTED_BUF_SIZE];

    memset(wcs,0,sizeof(wcs));

    if ( c == '\033' ) { /* ESC */
	CellModified = FALSE;
	clength = 0;
	bufp = buf;
	drawelt(DE, DE->crow, DE->ccol);
	cell_cursor_init(DE);
	return;
    } else
	CellModified = TRUE;

    if (clength == 0) {

	if (DE->crow == 0)	                        /* variable name */
	    currentexp = 3;
	else
	    switch(get_col_type(DE, DE->ccol + DE->colmin - 1)) {
	    case NUMERIC:
		currentexp = 1;
		break;
	    default:
		currentexp = 2;
	    }
	clearrect(DE);
	highlightrect(DE);
    }

    /* NA number? */
    if (get_col_type(DE, DE->ccol + DE->colmin - 1) == NUMERIC) {
	/* input numeric for NA of buffer , suppress NA etc.*/
	if(strcmp(buf, "NA") == 0 || strcmp(buf, "NaN") == 0 ||
	   strcmp(buf, "Inf") == 0 || strcmp(buf, "-Inf") == 0) {
	    buf[0] = '\0';
	    clength = 0;
	    bufp = buf;
	}
    }

    if (currentexp == 1) {	/* we are parsing a number */
	char *mbs = text;
	int i, cnt = (int)mbsrtowcs(wcs, (const char **)&mbs, (int) strlen(text)+1, NULL);

	for(i = 0; i < cnt; i++) {
	    switch (wcs[i]) {
	    case L'-':
		if (nneg == 0) nneg++; else goto donehc;
	    break;
	    case L'.':
		if (ndecimal == 0) ndecimal++; else goto donehc;
	    break;
	    case L'e':
	    case L'E':
		if (ne == 0) {
		    nneg = ndecimal = 0;	/* might have decimal in exponent */
		    ne++;
		} else goto donehc;
	    break;
	    case L'N':
		if(nneg) goto donehc;
	    case L'I':
		inSpecial++;
	    break;
	    default:
		if (!inSpecial && !iswdigit(wcs[i])) goto donehc;
		break;
	    }
	}
    }
    if (currentexp == 3) {
	char *mbs = text;
	int i, cnt = (int) mbsrtowcs(wcs, (const char **)&mbs, (int) strlen(text)+1, NULL);
	for(i = 0; i < cnt; i++) {
	    if (iswspace(wcs[i])) goto donehc;
	    if (clength == 0 && wcs[i] != L'.' && !iswalpha(wcs[i]))
		goto donehc;
	    else if (wcs[i] != L'.' && !iswalnum(wcs[i])) goto donehc;
	}
    }

    if (clength+strlen(text) > BOOSTED_BUF_SIZE - R_MB_CUR_MAX - 1) {
	warning("dataentry: expression too long");
	goto donehc;
    }

    /* as originally written, this left an undefined byte at
       the end of bufp, followed by a zero byte; luckily, the storage
       pointed to by bufp had already been zeroed, so the undefined
       byte was in fact zero.  */
    strcpy(bufp, text);
    bufp += (j = (int) strlen(text));
    clength += j;
    printstring(DE, buf, clength, DE->crow, DE->ccol, 1);
    return;

 donehc:
    bell();
}

static void printlabs(DEstruct DE)
{
    char clab[15];
    const char *p;
    int i;

    for (i = DE->colmin; i <= DE->colmax; i++) {
	p = get_col_name(DE, i);
	printstring(DE, p, (int) strlen(p), 0, i - DE->colmin + 1, 0);
    }
    for (i = DE->rowmin; i <= DE->rowmax; i++) {
	sprintf(clab, DE->labform, i);
	printstring(DE, clab, (int) strlen(clab), i - DE->rowmin + 1, 0, 0);
    }
}

	       /* ================ X11-specific ================ */

/* find out whether the button click was in the quit box */
static int checkquit(int xw)
{
    if (xw > box_coords[1] && xw < box_coords[0]) return 1;
    if (xw > box_coords[3] && xw < box_coords[2]) return 2;
    if (xw > box_coords[5] && xw < box_coords[4]) return 3;
    return 0;
}

/* when a buttonpress event happens find the square that is being
   pointed to if the pointer is in the header we need to see if the
   quit button was pressed and if so quit. This is done by having
   findcell return an int which is one if we should quit and zero
   otherwise */

static int findcell(DEstruct DE)
{

    int xw, yw, xr, yr, wcol=0, wrow, i, w;
    unsigned int keys;
    Window root, child;

    closerect(DE);
    XQueryPointer(iodisplay, DE->iowindow, &root, &child,
		  &xr, &yr, &xw, &yw, &keys);

    if (keys & Button1Mask) { /* left click */

	/* check to see if the click was in the header */

	if (yw < DE->hht + DE->bwidth) {
	    i =  checkquit(xw);
	    if (i == 1) return 1;
	    else if (i == 2) copycell(DE);
	    else if (i == 3) pastecell(DE, DE->crow, DE->ccol);
	    return 0;
	}


	/* see if it is in the row labels */
	if (xw < DE->bwidth + DE->boxw[0]) {
	    bell();
	    highlightrect(DE);
	    return 0;
	}
	/* translate to box coordinates */
	wrow = (yw - DE->bwidth - DE->hht) / DE->box_h;
	w = DE->bwidth + DE->boxw[0];
	for (i = 1; i <= DE->nwide; i++)
	    if((w += BOXW(i+DE->colmin-1)) > xw) {
		wcol = i;
		break;
	    }

	/* next check to see if it is in the column labels */

	if (yw < DE->hht + DE->bwidth + DE->box_h) {
	    if (xw > DE->bwidth + DE->boxw[0])
		popupmenu(DE, xr, yr, wcol, wrow);
	    else {
		highlightrect(DE);
		bell();
	    }
	} else if (wrow > DE->nhigh - 1 || wcol > DE->nwide -1) {
		/* off the grid */
		highlightrect(DE);
		bell();
	} else if (wcol != DE->ccol || wrow != DE->crow) {
	    DE->ccol = wcol;
	    DE->crow = wrow;
	}
    }
    if (keys & Button2Mask) { /* Paste */
	int row, col = 0;

	if (yw < DE->hht + DE->bwidth || xw < DE->bwidth + DE->boxw[0])
	    return 0;

	/* translate to box coordinates */
	row = (yw - DE->bwidth - DE->hht) / DE->box_h;
	w = DE->bwidth + DE->boxw[0];
	for (i = 1; i <= DE->nwide; i++)
	    if ((w += BOXW(i+DE->colmin-1)) > xw) {
		col = i;
		break;
	    }
	pastecell(DE, row, col);
    }
    highlightrect(DE);
    return 0;
}


/* Event Loop Functions */
#define mouseDown	ButtonPress
#define keyDown		KeyPress
#define activateEvt	MapNotify
#define updateEvt	Expose

static void eventloop(DEstruct DE)
{
    int done;
    DEEvent ioevent;
    caddr_t temp;

    done = 0;
    while (done == 0) {
	XNextEvent(iodisplay, &ioevent);
	XFindContext(iodisplay, ioevent.xany.window, deContext, &temp);
	if ((DEstruct) temp != DE) { /* so a View window */
	    if (WhichEvent(ioevent) == Expose)
		drawwindow((DEstruct) temp);
	} else {
	    if (XFilterEvent(&ioevent, None)){
		if(ioic){
		    XSetICFocus(ioic);
		    if (ioim_style & XIMPreeditPosition)
			calc_pre_edit_pos(DE);
		}
		continue;
	    }

	    switch (WhichEvent(ioevent)) {
	    case keyDown:/* KeyPress */
		doSpreadKey(DE, 0, &ioevent);
		break;
	    case Expose:
		while(XCheckTypedEvent(iodisplay, Expose, &ioevent))
		    ;
		/*
		 * XIM on  - KeyPress - Expose
		 * XIM off - KeyPress - KeyRelease
		 * colname change XIM on mode. type Backspace.
		 */
		if(DE->crow == 0){
		    drawwindow(DE);
		    printstring(DE, buf, clength, DE->crow, DE->ccol, 1);
		} else {
		    closerect(DE);
		    drawwindow(DE);
		    cell_cursor_init(DE);
		}
		break;
	    case activateEvt:/* MapNotify */
		closerect(DE);
		drawwindow(DE);
		cell_cursor_init(DE);
		break;
	    case mouseDown:/* ButtonPress */
		if(DE->isEditor) {
		    done  = doMouseDown(DE, &ioevent);
		    cell_cursor_init(DE);
		}
		break;
	    case MappingNotify:
		RefreshKeyboardMapping(&ioevent);
		break;
	    case ConfigureNotify:
		while(XCheckTypedEvent(iodisplay, ConfigureNotify, &ioevent))
		    ;
		doConfigure(DE, &ioevent);
		cell_cursor_init(DE);
		break;
	    case ClientMessage:
		if(ioevent.xclient.message_type == _XA_WM_PROTOCOLS
		   && ioevent.xclient.data.l[0] == DE->prot) {
		    /* user clicked on `close' aka `destroy' */
		    done = 1;
		}
		break;
	    }
	}
    }
}

static void R_ProcessX11Events(void *data)
{
    caddr_t temp;
    DEstruct DE = NULL;
    DEEvent ioevent;
    int done = 0;

    while (nView && XPending(iodisplay)) {
	XNextEvent(iodisplay, &ioevent);
	XFindContext(iodisplay, ioevent.xany.window, deContext, &temp);
	DE = (DEstruct) temp;
	switch (WhichEvent(ioevent)) {
	case keyDown:/* KeyPress */
	    doSpreadKey(DE, 0, &ioevent);
	    break;
	case Expose:
	    while(XCheckTypedEvent(iodisplay, Expose, &ioevent))
		;
	    drawwindow(DE);
	    break;
	case MappingNotify:
	    RefreshKeyboardMapping(&ioevent);
	    break;
	case ConfigureNotify:
	    while(XCheckTypedEvent(iodisplay, ConfigureNotify, &ioevent))
		;
	    doConfigure(DE, &ioevent);
	    cell_cursor_init(DE);
	    break;
	case activateEvt:/* MapNotify */
	    break;
	case ClientMessage:
	    if(ioevent.xclient.message_type == _XA_WM_PROTOCOLS
	       && ioevent.xclient.data.l[0] == DE->prot) {
		/* user clicked on `close' aka `destroy' */
		done = 1;
	    }
	    break;
	}
    }
    if(done) {
	R_ReleaseObject(DE->lens);
	R_ReleaseObject(DE->work);
	closewin(DE);
	free(DE);
	nView--;
	if(nView == 0) {
	    /* NB: this is removing the handler that is currently
	       being used: only OK to free here in R > 2.8.0 */
	    removeInputHandler(&R_InputHandlers,
			       getInputHandler(R_InputHandlers,fdView));
	    fdView = -1;
	    if(font_set) {
		XFreeFontSet(iodisplay, font_set);
		font_set = NULL;
	    }
	    XCloseDisplay(iodisplay);
	    iodisplay = NULL;
	}

    }
}

static int doMouseDown(DEstruct DE, DEEvent * event)
{
    return findcell(DE);
}

static void doSpreadKey(DEstruct DE, int key, DEEvent * event)
{
    KeySym iokey;
    char *text = "";

    iokey = GetKey(event);
    if(DE->isEditor) text = GetCharP(event);

    if (CheckControl(event))
	doControl(DE, event);
    else if ((iokey == XK_Return)  || (iokey == XK_KP_Enter) ||
	     (iokey == XK_Linefeed)|| (iokey == XK_Down))
	advancerect(DE, DOWN);
    else if (iokey == XK_Left)
	advancerect(DE, LEFT);
    else if (iokey == XK_Right)
	advancerect(DE, RIGHT);
    else if (iokey == XK_Up)
	advancerect(DE, UP);
#ifdef XK_Page_Up
    else if (iokey == XK_Page_Up) {
	int i = DE->rowmin - DE->nhigh + 2;
	jumpwin(DE, DE->colmin, max(1, i));
	cell_cursor_init(DE);
    }
#elif defined(XK_Prior)
    else if (iokey == XK_Prior) {
	int i = DE->rowmin - DE->nhigh + 2;
	jumpwin(DE, DE->colmin, max(1, i));
	cell_cursor_init(DE);
    }
#endif
#ifdef XK_Page_Down
    else if (iokey == XK_Page_Down) {
	if(DE->isEditor)
	    jumpwin(DE, DE->colmin, DE->rowmax);
	else {
	    int i = DE->ymaxused - DE->nhigh + 2;
            jumpwin(DE, DE->colmin, max(1, min(i, DE->rowmax)));
	}
	cell_cursor_init(DE);
    }
#elif defined(XK_Next)
    else if (iokey == XK_Next) {
	if(DE->isEditor)
	    jumpwin(DE, DE->colmin, DE->rowmax);
	else {
	    int i = DE->ymaxused - DE->nhigh + 2;
            jumpwin(DE, DE->colmin, max(1, min(i, DE->rowmax)));
	}
	cell_cursor_init(DE);
    }
#endif
    else if (DE->isEditor && (iokey == XK_BackSpace || iokey == XK_Delete)) {
	if (clength > 0) {
	    int last_w ;
	    last_w = last_wchar_bytes(NULL);
	    clength -= last_w;
	    bufp -= last_w;
	    *bufp = '\0';
	    CellModified = TRUE;
	    printstring(DE, buf, clength, DE->crow, DE->ccol, 1);
	} else bell();
    }
    else if (iokey == XK_Tab) {
	if(CheckShift(event)) advancerect(DE, LEFT);
	else advancerect(DE, RIGHT);
    }
    else if (iokey == XK_Home) {
	jumpwin(DE, 1, 1);
	downlightrect(DE);
	DE->crow = DE->ccol = 1;
	highlightrect(DE);
	cell_cursor_init(DE);
    }
    else if (iokey == XK_End) {
	int i = DE->ymaxused - DE->nhigh + 2, j, w = 0 ;
	/* Try to work out which cols we can fit in */
	for(j = DE->xmaxused;j >= 0; j--) {
	    w += BOXW(j);
	    if(w > DE->fullwindowWidth) break;
	}
	jumpwin(DE, min(1 + max(j, 0), DE->xmaxused), max(i, 1));
	downlightrect(DE);
	DE->crow = DE->ymaxused - DE->rowmin + 1;
	DE->ccol = DE->xmaxused - DE->colmin + 1;
	highlightrect(DE);
	cell_cursor_init(DE);
    }
    else if (IsModifierKey(iokey)) {
    }
    else if(DE->isEditor) {
	handlechar(DE, text);
    }
}


static int WhichEvent(DEEvent ioevent)
{
    return ioevent.type;
}

static KeySym GetKey(DEEvent * event)
{
    char text[1];
    KeySym iokey;

    XLookupString((XKeyEvent *)event, text, 1, &iokey, NULL);
    return iokey;
}

static char *GetCharP(DEEvent * event)
{
    static char text[BOOSTED_BUF_SIZE];
    KeySym iokey;

    memset(text,0,sizeof(text));

    if(mbcslocale) {
#ifdef HAVE_XUTF8LOOKUPSTRING
	if(utf8locale)
	    Xutf8LookupString(ioic, (XKeyEvent *)event,
			      text, sizeof(text) - clength,
			      &iokey, &status);
	else
#endif
	    XmbLookupString(ioic, (XKeyEvent *)event,
			    text, sizeof(text) - clength,
			    &iokey, &status);
	/* FIXME check the return code */
	if(status == XBufferOverflow)
	    warning("dataentry: expression too long");
    } else
	XLookupString((XKeyEvent *)event,
		      text, sizeof(text) - clength,
		      &iokey, NULL);
    return text;
}

static int CheckControl(DEEvent * event)
{
    return (*event).xkey.state & ControlMask;
}

static int CheckShift(DEEvent * event)
{
    return (*event).xkey.state & ShiftMask;
}

static void doControl(DEstruct DE, DEEvent * event)
{
    int i;
    char text[1];
    KeySym iokey;

    (*event).xkey.state = 0;
    XLookupString((XKeyEvent *)event, text, 1, &iokey, NULL);
    /* one row overlap when scrolling: top line <--> bottom line */
    switch (text[0]) {
	case 'b':
	    i = DE->rowmin - DE->nhigh + 2;
	    jumpwin(DE, DE->colmin, max(1, i));
	    break;
	case 'f':
	    jumpwin(DE, DE->colmin, DE->rowmax);
	    break;
	case 'l':
	    closerect(DE);
	    for (i = 1 ; i <= min(100, DE->xmaxused); i++)
		DE->boxw[i] = get_col_width(DE, i);
	    closerect(DE);
	    drawwindow(DE);
	    break;
    }
    cell_cursor_init(DE);
}


static void doConfigure(DEstruct DE, DEEvent * event)
{
    if ((DE->fullwindowWidth != (*event).xconfigure.width) ||
	(DE->fullwindowHeight != (*event).xconfigure.height)) {
	closerect(DE);
	drawwindow(DE);
    }
}

static void RefreshKeyboardMapping(DEEvent * event)
{
    XRefreshKeyboardMapping((XMappingEvent *)event);
}

/* Initialize/Close Windows */

void closewin(DEstruct DE)
{
    XFreeGC(iodisplay, DE->iogc);
    if(mbcslocale  && DE->isEditor) {
	XDestroyIC(ioic);
	XCloseIM(ioim);
    }
    XDestroyWindow(iodisplay, DE->iowindow);
    /* XCloseDisplay(iodisplay); */
    Rsync(DE);
}

#define USE_Xt 1

#ifdef USE_Xt
#include <X11/StringDefs.h>
#include <X11/Intrinsic.h>
#include <X11/Shell.h>
typedef struct gx_device_X_s {
    Pixel background, foreground, borderColor;
    Dimension borderWidth;
    String geometry;
} gx_device_X;

/* (String) casts are here to suppress warnings about discarding `const' */
#define RINIT(a,b,t,s,o,it,n)\
  {(String)(a), (String)(b), (String)t, sizeof(s),\
   XtOffsetOf(gx_device_X, o), (String)it, (n)}
#define rpix(a,b,o,n)\
  RINIT(a,b,XtRPixel,Pixel,o,XtRString,(XtPointer)(n))
#define rdim(a,b,o,n)\
  RINIT(a,b,XtRDimension,Dimension,o,XtRImmediate,(XtPointer)(n))
#define rstr(a,b,o,n)\
  RINIT(a,b,XtRString,String,o,XtRString,(char*)(n))

static XtResource x_resources[] = {
    rpix(XtNforeground, XtCForeground, foreground, "XtDefaultForeground"),
    rpix(XtNbackground, XtCBackground, background, "XtDefaultBackground"),
    rstr(XtNgeometry, XtCGeometry, geometry, NULL),
};

static const int x_resource_count = XtNumber(x_resources);
static gx_device_X xdev;
#endif

/* NB: Keep this in sync with similar handler in devX11.c */
static int R_X11Err(Display *dsp, XErrorEvent *event)
{
    char buff[1000];
    /* for tcl/tk */
    if (event->error_code == BadWindow) return 0;

    XGetErrorText(dsp, event->error_code, buff, 1000);
    warning(_("X11 protocol error: %s"), buff);
    return 0;
}


static int NORET R_X11IOErr(Display *dsp)
{
    error("X11 fatal IO error: please save work and shut down R");
}

/* set up the window, print the grid and column/row labels */

static Rboolean initwin(DEstruct DE, const char *title) /* TRUE = Error */
{
    int i, twidth, w, minwidth, labdigs;
    int ioscreen;
    unsigned long iowhite, ioblack;
    char digits[] = "123456789.0";
    char             *font_name="9x15";
    Window root;
    XEvent ioevent;
    XSetWindowAttributes winattr;
    XWindowAttributes attribs;
    XSizeHints *hint;
    unsigned long fevent=0UL;
    int j,k;
    XVaNestedList   xva_nlist;
    XPoint xpoint;

    strcpy(copycontents, "");

    if (!XSupportsLocale ())
	warning("locale not supported by Xlib: some X ops will operate in C locale");
    if (!XSetLocaleModifiers ("")) warning("X cannot set locale modifiers");

    if(!iodisplay) {
	if ((iodisplay = XOpenDisplay(NULL)) == NULL) {
	    warning("unable to open display");
	    return TRUE;
	}
	deContext = XUniqueContext();
	XSetErrorHandler(R_X11Err);
	XSetIOErrorHandler(R_X11IOErr);
    }


    /* Get Font Loaded if we can */

    if(mbcslocale) {
	int  missing_charset_count;
	char **missing_charset_list;
	char *def_string;
	char opt_fontset_name[512];

	/* options("X11fonts")[1] read font name */
	SEXP opt = GetOption1(install("X11fonts"));
	if(isString(opt)) {
	    const char *s = CHAR(STRING_ELT(opt, 0));
	    sprintf(opt_fontset_name, s, "medium", "r", 12);
	} else strcpy(opt_fontset_name, fontset_name);

	if(font_set == NULL) {
	    font_set = XCreateFontSet(iodisplay, opt_fontset_name,
				      &missing_charset_list,
				      &missing_charset_count, &def_string);
	    if (missing_charset_count) XFreeStringList(missing_charset_list);
	}
	if (font_set == NULL) {
	    warning("unable to create fontset %s", opt_fontset_name);
	    return TRUE; /* ERROR */
	}
    } else {
	DE->font_info = XLoadQueryFont(iodisplay, font_name);
	if (DE->font_info == NULL) {
	    warning("unable to load font %s", font_name);
	    return TRUE; /* ERROR */
	}
    }

    /* find out how wide the input boxes should be and set up the
       window size defaults */

    DE->nboxchars = asInteger(GetOption1(install("de.cellwidth")));
    if (DE->nboxchars == NA_INTEGER || DE->nboxchars < 0) DE->nboxchars = 0;

    twidth = textwidth(DE, digits, (int) strlen(digits));

    if (DE->nboxchars > 0) twidth = (twidth * DE->nboxchars)/10;
    DE->box_w = twidth + 4;
    if(mbcslocale) {
	XFontSetExtents *extent = XExtentsOfFontSet(font_set);
	char **ml;
	DE->box_h = (extent->max_logical_extent.height)
	    + (extent->max_logical_extent.height / 5) + 4;
	font_set_cnt = XFontsOfFontSet(font_set, &fs_list, &ml);
	DE->text_offset = 2 + fs_list[0]->max_bounds.descent;
    } else {
	DE->box_h = DE->font_info->max_bounds.ascent
	    + DE->font_info->max_bounds.descent + 4;
	DE->text_offset = 2 + DE->font_info->max_bounds.descent;
    }
    DE->windowHeight = 26 * DE->box_h + DE->hht + 2;
    /* this used to presume 4 chars sufficed for row numbering */
    labdigs = max(3, 1+ (int) floor(log10((double)DE->ymaxused)));
    sprintf(DE->labform, "%%%dd", labdigs);
    DE->boxw[0] = (int)( 0.1*labdigs*textwidth(DE, "0123456789", 10)) +
	textwidth(DE, " ", 1) + 8;
    for(i = 1; i < 100; i++) DE->boxw[i] = get_col_width(DE, i);

    /* try for a window width that covers all the columns, or is around
       800 pixels */
    w = DE->windowWidth = 0;
    for(i = 0; i <= DE->xmaxused; i++) {
	w += DE->boxw[i];
	if(w > 800) {
	    DE->windowWidth = w - DE->boxw[i];
	    break;
	}
    }
    if(DE->windowWidth == 0) DE->windowWidth = w;
    DE->windowWidth += 2;
    /* allow enough width for buttons */
    minwidth = (int)(7.5 * textwidth(DE, "Paste", 5));
    if(DE->windowWidth < minwidth) DE->windowWidth = minwidth;

    ioscreen = DefaultScreen(iodisplay);
    iowhite = WhitePixel(iodisplay, ioscreen);
    ioblack = BlackPixel(iodisplay, ioscreen);


    hint = XAllocSizeHints();

    hint->x = 0;
    hint->y = 0;
    hint->width = DE->windowWidth;
    hint->height = DE->windowHeight;
    hint->flags = PPosition | PSize;
    /*
     * not necessary?
    hints.flags = InputHint;
    hints.input = True;
    */
    root = DefaultRootWindow(iodisplay);

#ifdef USE_Xt
    {
	XtAppContext app_con;
	Widget toplevel;
	Display *xtdpy;
	int zero = 0;

	XtToolkitInitialize();
	app_con = XtCreateApplicationContext();
	/* XtAppSetFallbackResources(app_con, x_fallback_resources);*/
	xtdpy = XtOpenDisplay(app_con, NULL, "r_dataentry", "R_dataentry",
			      NULL, 0, &zero, NULL);
	toplevel = XtAppCreateShell(NULL, "R_dataentry",
				    applicationShellWidgetClass,
				    xtdpy, NULL, 0);
	XtGetApplicationResources(toplevel, (XtPointer) &xdev,
				  x_resources,
				  x_resource_count,
				  NULL, 0);
	XtDestroyWidget(toplevel);
	XtCloseDisplay(xtdpy);
	XtDestroyApplicationContext(app_con);
	if (xdev.geometry != NULL) {
	    char gstr[40];
	    int bitmask;

	    sprintf(gstr, "%dx%d+%d+%d", hint->width,
		    hint->height, hint->x, hint->y);
	    bitmask = XWMGeometry(iodisplay, DefaultScreen(iodisplay),
				  xdev.geometry, gstr,
				  1,
				  hint,
				  &hint->x, &hint->y,
				  &hint->width, &hint->height,
				  &hint->win_gravity);

	    if (bitmask & (XValue | YValue))
		hint->flags |= USPosition;
	    if (bitmask & (WidthValue | HeightValue))
		hint->flags |= USSize;
	}
	ioblack = xdev.foreground;
	iowhite = xdev.background;
    }
#endif
    if ((DE->iowindow = XCreateSimpleWindow(
	     iodisplay,
	     root,
	     hint->x,
	     hint->y,
	     hint->width,
	     hint->height,
	     DE->bwidth,
	     ioblack,
	     iowhite)) == 0) {
	warning("unable to open window for data editor");
	return TRUE;
    }

    /*
    XSetStandardProperties(iodisplay, DE->iowindow, ioname, ioname, None,
			   (char **)NULL, 0, iohint);
    */
    XSetWMNormalHints(iodisplay, DE->iowindow, hint);
    XFree(hint);


    winattr.backing_store = WhenMapped;
    XChangeWindowAttributes(iodisplay, DE->iowindow, CWBackingStore,
			    &winattr);

    /* set up protocols so that window manager sends */
    /* me an event when user "destroys" window */
    if(!_XA_WM_PROTOCOLS)
	_XA_WM_PROTOCOLS = XInternAtom(iodisplay, "WM_PROTOCOLS", 0);
    DE->prot = XInternAtom(iodisplay, "WM_DELETE_WINDOW", 0);
    XSetWMProtocols(iodisplay, DE->iowindow, &DE->prot, 1);
    /*
     * not necessary
    XSetWMHints(iodisplay, DE->iowindow, &hints);
     */

    DE->iogc = XCreateGC(iodisplay, DE->iowindow, 0, 0);

    if(mbcslocale && DE->isEditor) {
	ioim = XOpenIM(iodisplay, NULL, NULL, NULL);
	if(!ioim) {
	    XDestroyWindow(iodisplay, DE->iowindow);
	    XCloseDisplay(iodisplay);
	    warning("unable to open X Input Method");
	    return TRUE;
	}

	/* search supported input style */
	XGetIMValues(ioim, XNQueryInputStyle, &ioim_styles,NULL);
	for(i = 0; i < ioim_styles->count_styles; i++) {
	    for(j = 0; preedit_styles[j]; j++){
		for(k = 0; status_styles[k]; k++){
		    ioim_style = (preedit_styles[j] | status_styles[k]);
		    if( ioim_styles->supported_styles[i] == ioim_style) {
			goto loop_out;
		    }
		}
	    }
	}
    loop_out:

	/* create input context */
	xpoint.x = 0; xpoint.y=0;
	xva_nlist = XVaCreateNestedList(0, XNFontSet, font_set,
					XNSpotLocation, &xpoint, NULL);

	ioic = XCreateIC(ioim,
			 XNInputStyle, ioim_style,
			 XNClientWindow,DE->iowindow,
			 XNFocusWindow,DE->iowindow,
			 XNPreeditAttributes, xva_nlist,
			 XNStatusAttributes, xva_nlist,
			 NULL);
	XFree(xva_nlist);
	if(!ioic) {
	    XCloseIM(ioim);
	    XDestroyWindow(iodisplay, DE->iowindow);
	    XCloseDisplay(iodisplay);
	    warning("unable to open X Input Context");
	    return TRUE;
	}

	/* get XIM processes event. */
	XGetICValues(ioic, XNFilterEvents, &fevent, NULL);
    }

    if(!mbcslocale)
	XSetFont(iodisplay, DE->iogc, DE->font_info->fid);

    XSetBackground(iodisplay, DE->iogc, iowhite);
    XSetForeground(iodisplay, DE->iogc, ioblack);
    XSetLineAttributes(iodisplay, DE->iogc, 1, LineSolid, CapRound,
		       JoinRound);

    /*
    XSelectInput(iodisplay, DE->iowindow,
		 ButtonPressMask | KeyPressMask
		 | ExposureMask | StructureNotifyMask | fevent);
    */

    XSelectInput(iodisplay, DE->iowindow,
		 ButtonPressMask
		 | KeyPressMask
		 | StructureNotifyMask
		 | ExposureMask
		 | EnterWindowMask
		 | LeaveWindowMask
		 | fevent);
    XMapRaised(iodisplay, DE->iowindow);

    /* now set up the menu-window, for now use the same text
       dimensions as above */

    /* font size consideration */
    for(i = 0; i < (sizeof(menu_label)/sizeof(char *)); i++)
	twidth = (twidth<textwidth(DE, menu_label[i],(int) strlen(menu_label[i]))) ?
	    textwidth(DE, menu_label[i],(int) strlen(menu_label[i])) : twidth;

    menuwindow = XCreateSimpleWindow(iodisplay, root, 0, 0, twidth,
				     4 * DE->box_h, 2, ioblack, iowhite);
    for (i = 0; i < 4; i++) {
	menupanes[i] = XCreateSimpleWindow(iodisplay, menuwindow, 0,
					   DE->box_h * i, twidth, DE->box_h,
					   1, ioblack, iowhite);
	XSelectInput(iodisplay, menupanes[i],
		     ButtonPressMask | ButtonReleaseMask | ExposureMask
		     );
    }

    /* XMapSubwindows(iodisplay, menuwindow); */


    XStoreName(iodisplay, DE->iowindow, title);
    winattr.override_redirect = True;
    XChangeWindowAttributes(iodisplay, menuwindow,
			    CWBackingStore | CWOverrideRedirect, &winattr);
    Rsync(DE);

    /* this next sequence makes sure the window is up and ready before
       you start drawing in it */

    XNextEvent(iodisplay, &ioevent);
    if (ioevent.xany.type == Expose) {
	while (ioevent.xexpose.count)
	    XNextEvent(iodisplay, &ioevent);
    }
    XGetWindowAttributes(iodisplay, DE->iowindow, &attribs);
    DE->bwidth = attribs.border_width;
    DE->fullwindowWidth = attribs.width;
    DE->fullwindowHeight = attribs.height;


    /* set the active rectangle to be the upper left one */
    DE->crow = 1;
    DE->ccol = 1;
    CellModified = FALSE;
    XSaveContext(iodisplay, DE->iowindow, deContext, (caddr_t) DE);
    return FALSE;/* success */
}

/* MAC/X11 BASICS */

static void bell()
{
    XBell(iodisplay, 20);
}

static void cleararea(DEstruct DE, int xpos, int ypos, int width, int height)
{
    XClearArea(iodisplay, DE->iowindow, xpos, ypos, width, height, 0);
}

static void clearwindow(DEstruct DE)
{
    XClearWindow(iodisplay, DE->iowindow);
}

static void copyarea(DEstruct DE, int src_x, int src_y, int dest_x, int dest_y)
{
    int mx = max(src_x, dest_x), my = max(src_y, dest_y);
    XCopyArea(iodisplay, DE->iowindow, DE->iowindow, DE->iogc,
	      src_x, src_y,
	      DE->fullwindowWidth - mx, DE->fullwindowHeight - my,
	      dest_x, dest_y);
    Rsync(DE);
}

static void copyH(DEstruct DE, int src_x, int dest_x, int width)
{
    XCopyArea(iodisplay, DE->iowindow, DE->iowindow, DE->iogc,
	      src_x+DE->bwidth, DE->hht,
	      width, DE->windowHeight+1, dest_x+DE->bwidth, DE->hht);
}

static void drawrectangle(DEstruct DE,
			  int xpos, int ypos, int width, int height,
			  int lwd, int fore)
{
#ifdef USE_Xt
    if (fore == 0)
	XSetForeground(iodisplay, DE->iogc, xdev.background);
    else
	XSetForeground(iodisplay, DE->iogc, xdev.foreground);
#else
    if (fore == 0)
	XSetForeground(iodisplay, DE->iogc,
		       WhitePixel(iodisplay, DefaultScreen(iodisplay)));
    else
	XSetForeground(iodisplay, DE->iogc,
		       BlackPixel(iodisplay, DefaultScreen(iodisplay)));
#endif
    XSetLineAttributes(iodisplay, DE->iogc, lwd, LineSolid,
		       CapRound, JoinRound);
    XDrawRectangle(iodisplay, DE->iowindow, DE->iogc, xpos, ypos,
		   width, height);
}

static void drawtext(DEstruct DE, int xpos, int ypos, char *text, int len)
{
    if(mbcslocale)
#ifdef HAVE_XUTF8DRAWIMAGESTRING
	if(utf8locale)
	    Xutf8DrawImageString(iodisplay, DE->iowindow, font_set,
				 DE->iogc, xpos, ypos,text, len);
	else
#endif
	    XmbDrawImageString(iodisplay, DE->iowindow, font_set,
			       DE->iogc, xpos, ypos,text, len);
    else
	XDrawImageString(iodisplay, DE->iowindow, DE->iogc,
			 xpos, ypos, text, len);
    Rsync(DE);
}

static void Rsync(DEstruct DE)
{
    XSync(iodisplay, 0);
}

static int textwidth(DEstruct DE, const char *text, int nchar)
{
    int ans;
    char *buf = CallocCharBuf(nchar);
    strncpy(buf, text, nchar);
    if(mbcslocale) {
#ifdef HAVE_XUTF8TEXTESCAPEMENT
	if (utf8locale)
	    ans = Xutf8TextEscapement(font_set, buf, nchar);
	else
#endif
	    ans = XmbTextEscapement(font_set, buf, nchar);
	R_Free(buf);
	return ans;
    }
    ans = XTextWidth(DE->font_info, buf, nchar);
    R_Free(buf);
    return ans;
}

/* Menus */

void popupmenu(DEstruct DE, int x_pos, int y_pos, int col, int row)
{
    int i, button, popupcol = col + DE->colmin - 1;
    const char *name;
    char clab[20];
    XEvent event;
    Window selected_pane;
    SEXP tvec;

    XMoveWindow(iodisplay, menuwindow, x_pos, y_pos);
    XMapSubwindows(iodisplay, menuwindow);
    XMapRaised(iodisplay, menuwindow);

    /* now fill in the menu panes with the correct information */

    if (popupcol > DE->xmaxused) {
	/* extend work, names and lens */
	REPROTECT(DE->work = lengthgets(DE->work, popupcol), DE->wpi);
	REPROTECT(DE->names = lengthgets(DE->names, popupcol), DE->npi);
	for (i = DE->xmaxused+1; i < popupcol; i++) {
	    sprintf(clab, "var%d", i + 1);
	    SET_STRING_ELT(DE->names, i, mkChar(clab));
	}
	REPROTECT(DE->lens = lengthgets(DE->lens, popupcol), DE->lpi);
	DE->xmaxused = popupcol;
    }
    tvec = VECTOR_ELT(DE->work, popupcol - 1);
    name = CHAR(STRING_ELT(DE->names, popupcol - 1));
    if(mbcslocale)
#ifdef HAVE_XUTF8DRAWSTRING
	if(utf8locale)
	    Xutf8DrawString(iodisplay,
			    menupanes[0],
			    font_set, DE->iogc, 3, DE->box_h - 3, name,
			    (int) strlen(name));
	else
#endif
	    XmbDrawString(iodisplay,
			  menupanes[0],
			  font_set, DE->iogc, 3, DE->box_h - 3, name,
			  (int) strlen(name));
    else
	XDrawString(iodisplay,
		    menupanes[0], DE->iogc, 3, DE->box_h - 3, name,
		    (int) strlen(name));
    for (i = 1; i < 4; i++)
	if(mbcslocale)
#ifdef HAVE_XUTF8DRAWSTRING
	    if(utf8locale)
		Xutf8DrawString(iodisplay,
				menupanes[i],
				font_set, DE->iogc, 3, DE->box_h - 3,
				menu_label[i - 1], (int) strlen(menu_label[i - 1]));
	    else
#endif
		XmbDrawString(iodisplay,
			      menupanes[i],
			      font_set, DE->iogc, 3, DE->box_h - 3,
			      menu_label[i - 1], (int) strlen(menu_label[i - 1]));
	else
	    XDrawString(iodisplay,
			menupanes[i], DE->iogc, 3, DE->box_h - 3,
			menu_label[i - 1], (int) strlen(menu_label[i - 1]));

    if (isNull(tvec) || TYPEOF(tvec) == REALSXP)
	if(mbcslocale)
#ifdef HAVE_XUTF8DRAWSTRING
	    if(utf8locale)
		Xutf8DrawString(iodisplay,
				menupanes[1],
				font_set, DE->iogc, 0, DE->box_h - 3,
				"*", 1);
	    else
#endif
		XmbDrawString(iodisplay,
			      menupanes[1],
			      font_set, DE->iogc, 0, DE->box_h - 3,
			      "*", 1);
	else
	    XDrawString(iodisplay, menupanes[1], DE->iogc, 0, DE->box_h - 3,
			"*", 1);
    else
	if(mbcslocale)
#ifdef HAVE_XUTF8DRAWSTRING
	    if(utf8locale)
		Xutf8DrawString(iodisplay,
				menupanes[2],
				font_set, DE->iogc, 0, DE->box_h - 3,
				"*", 1);
	    else
#endif
		XmbDrawString(iodisplay,
			      menupanes[2],
			      font_set, DE->iogc, 0, DE->box_h - 3,
			      "*", 1);
	else
	    XDrawString(iodisplay, menupanes[2], DE->iogc, 0, DE->box_h - 3,
			"*", 1);

/*
  start an event loop; we're looking for a button press and a button
  release in the same window
*/

    while (1) {
	XNextEvent(iodisplay, &event);

	/* event is processed with input method */

	if (event.type == ButtonPress) {
	    button = event.xbutton.button;
	    selected_pane = event.xbutton.window;
	    for (i = 0; selected_pane != menupanes[i]; i++)
		if (i >= 3) goto done;
	    while (1) {
		while (XCheckTypedEvent(iodisplay, ButtonPress, &event));
		XMaskEvent(iodisplay, ButtonReleaseMask, &event);
		if (event.xbutton.button == button)
		    break;
	    }
	    if (selected_pane == event.xbutton.window) {
		for (i = 0; selected_pane != menupanes[i]; i++);
		switch (i) {
		case 0:
		    bell();
		    break;
		case 1:
		    if (isNull(tvec))
			SET_VECTOR_ELT(DE->work, popupcol - 1,
				       ssNewVector(REALSXP, 100));
		    else
			SET_VECTOR_ELT(DE->work, popupcol - 1,
				       coerceVector(tvec, REALSXP));
		    goto done;
		case 2:
		    if (isNull(tvec))
			SET_VECTOR_ELT(DE->work, popupcol - 1,
				       ssNewVector(STRSXP, 100));
		    else {
			SET_VECTOR_ELT(DE->work, popupcol - 1,
				       coerceVector(tvec, STRSXP));
		    }

		    goto done;
		case 3:
		    closerect(DE);
		    DE->ccol = col;
		    DE->crow = 0;
		    clearrect(DE);
		    goto done;
		}
	    }
	}
	/* this doesn't work and perhaps I should move it up to the
	   main control loop */
	else if (event.type == Expose) {
	    if (event.xexpose.window == menuwindow) {
		XDrawString(iodisplay, menupanes[0], DE->iogc, 3,
			    DE->box_h - 3, name, (int) strlen(name));
		for (i = 1; i < 4; i++)
		    XDrawString(iodisplay, menupanes[i], DE->iogc, 3,
				DE->box_h - 3,
				menu_label[i - 1], (int) strlen(menu_label[i - 1]));
	    }
	}
    }
done:
    popdownmenu(DE);
    highlightrect(DE);
}

void popdownmenu(DEstruct DE)
{
    XUnmapWindow(iodisplay, menuwindow);
    XUnmapSubwindows(iodisplay, menuwindow);
}

static void copycell(DEstruct DE)
{
  /*
   * whichrow = crow + colmin - 1 => whichrow = crow + rowmin - 1
   *                   ^^^                             ^^^
   */
    int i, whichrow = DE->crow + DE->rowmin - 1,
	whichcol = DE->ccol + DE->colmin -1;
    SEXP tmp;

    if (whichrow == 0) {
	/* won't have  cell here */
    } else {
	strcpy(copycontents, "");
	if (length(DE->work) >= whichcol) {
	    tmp = VECTOR_ELT(DE->work, whichcol - 1);
	    if (tmp != R_NilValue &&
		(i = whichrow - 1) < LENGTH(tmp) ) {
		PrintDefaults();
		if (TYPEOF(tmp) == REALSXP) {
			strncpy(copycontents, EncodeElement(tmp, i, 0, '.'),
				BOOSTED_BUF_SIZE-1);
			copycontents[BOOSTED_BUF_SIZE-1]='\0';
		} else if (TYPEOF(tmp) == STRSXP) {
		    if (STRING_ELT(tmp, i) != ssNA_STRING) {
			strncpy(copycontents, EncodeElement(tmp, i, 0, '.'),
				BOOSTED_BUF_SIZE-1);
			copycontents[BOOSTED_BUF_SIZE-1]='\0';
		    }
		}
	    }
	}
    }
    highlightrect(DE);
}

static void pastecell(DEstruct DE, int row, int col)
{
    downlightrect(DE);
    DE->crow = row; DE->ccol = col;
    if (strlen(copycontents)) {
	strcpy(buf, copycontents);
	clength = (int) strlen(copycontents);
	bufp = buf + clength;
	CellModified = TRUE;
    }
    closerect(DE);
    highlightrect(DE);
}

static void calc_pre_edit_pos(DEstruct DE)
{
    XVaNestedList   xva_nlist;
    XPoint          xpoint;
    int i;
    int w;

    xpoint.x = (short) DE->boxw[0];
    for (i = 1; i < DE->ccol; i++)
	xpoint.x += BOXW(DE->colmin + i - 1);
#ifdef HAVE_XUTF8TEXTESCAPEMENT
    if(utf8locale)
	w = Xutf8TextEscapement(font_set, buf, clength);
    else
#endif
	w = XmbTextEscapement(font_set, buf, clength);
    xpoint.x += (w > BOXW(DE->colmin + DE->ccol - 1)) ?
	BOXW(DE->colmin + DE->ccol - 1) : w;
    xpoint.x += DE->text_offset;
    xpoint.y = (short)(DE->hht + (DE->crow+1) * DE->box_h - DE->text_offset);

    /*
      <FIXME>
      I may depend on implementation of XIM, but I do not obey,
      setting value, and investigation in various implementation
      system is need.
      It is only a problem in an appearance.
    */
    xva_nlist = XVaCreateNestedList(0,
				    XNSpotLocation, &xpoint,
				    XNFontSet, font_set,
				    NULL);
    XSetICValues(ioic, XNPreeditAttributes, xva_nlist, NULL);

    XFree(xva_nlist);
    return;
}

/* last character bytes */
static int last_wchar_bytes(char *str)
{
    wchar_t   wcs[BOOSTED_BUF_SIZE];
    mbstate_t mb_st;
    int cnt;
    char last_mbs[8];
    char *mbs;
    size_t bytes;

    mbs = (str == NULL) ? buf : str;

    memset(wcs, 0 ,sizeof(wcs));
    memset(&mb_st,0, sizeof(mbstate_t));

    if((int)-1 == (cnt = (int)mbsrtowcs(wcs, (const char **)&mbs,
					(int) strlen(mbs), &mb_st))) {
	return 0;
    }
    if(wcs[0] == L'\0') return 0;

    memset(last_mbs, 0, sizeof(last_mbs));
    bytes = wcrtomb(last_mbs, wcs[cnt-1], &mb_st); /* -Wall */
    return (int) bytes;
}

