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

/* The version for R 2.1.0 is partly based on patches by
   Ei-ji Nakama for use in Japanese.

   <MBCS> all the strings manipulated here like display and fonts specs
   are probably ASCII, or at least start with ASCII in the part searched.
*/

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

#include <Defn.h>

/* rint is C99 */
#ifdef HAVE_RINT
#define R_rint(x) rint(x)
#else
#define R_rint(x) ((int) x + 0.5)
#endif

/* needed on Solaris */
#define XK_MISCELLANY
#include <stdio.h>
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xatom.h>
#include <X11/Xutil.h>
#include <X11/cursorfont.h>
#include <X11/Intrinsic.h>	/*->	Xlib.h	Xutil.h Xresource.h .. */
#ifdef HAVE_X11_Xmu
# include <X11/Xmu/Atoms.h>
#endif
#include <X11/keysymdef.h>


#define R_USE_PROTOTYPES 1
#include <R_ext/GraphicsEngine.h>
#include "Fileio.h"		/* R_fopen */
#include "rotated.h"		/* 'Public' routines from here */
/* For the input handlers of the event loop mechanism: */
#include <R_ext/eventloop.h>
#include <R_ext/Memory.h>	/* vmaxget */

/* In theory we should do this, but it works less well
# ifdef X_HAVE_UTF8_STRING
#  define HAVE_XUTF8TEXTESCAPEMENT 1
#  define HAVE_XUTF8TEXTEXTENTS 1
# endif */

typedef int (*X11IOhandler)(Display *);

#include "devX11.h"
#include "rlogo_icon.h" /* hard-coded ARGB icon */

#include <Rmodules/RX11.h>

static Cursor watch_cursor = (Cursor) 0 ;
static Cursor arrow_cursor = (Cursor) 0 ;
static Cursor cross_cursor = (Cursor) 0 ;


#define MM_PER_INCH	25.4			/* mm -> inch conversion */

#define X_BELL_VOLUME 0 /* integer between -100 and 100 for the volume
			    of the bell in locator. */
			/* Note: This is in relation to
			the general bell level. Was 50, but if > 0
			then "xset b off" will not disable the
			locator bell - pd 2002-3-11 */
/* a colour used to represent the background on png if transparent
   NB: must be grey as used as RGB and BGR
*/
#define PNG_TRANS 0xfefefe

	/********************************************************/
	/* If there are resources that are shared by all devices*/
	/* of this type, you may wish to make them globals	*/
	/* rather than including them in the device-specific	*/
	/* parameters structure (especially if they are large !)*/
	/********************************************************/

	/* X11 Driver Specific parameters
	 * with only one copy for all x11 devices */

static Display *display;			/* Display */
static char dspname[101]="";
static int screen;				/* Screen */
static Window rootwin;				/* Root Window */
static Visual *visual;				/* Visual */
static int depth;				/* Pixmap depth */
static int Vclass;				/* Visual class */
static X_COLORTYPE model;			/* User color model */
static int maxcubesize;				/* Max colorcube size */
static XSetWindowAttributes attributes;		/* Window attributes */
static Colormap colormap;			/* Default color map */
static int whitepixel;				/* bg overlaying canvas */
static XContext devPtrContext;
static Atom _XA_WM_PROTOCOLS, protocol;

static Rboolean displayOpen = FALSE;
static Rboolean inclose = FALSE;
static int numX11Devices = 0;

	/********************************************************/
	/* There must be an entry point for the device driver	*/
	/* which will create device-specific resources,		*/
	/* initialise the device-specific parameters structure	*/
	/* and return whether the setup succeeded		*/
	/* This is called by the graphics engine when the user	*/
	/* creates a new device of this type			*/
	/********************************************************/


	/********************************************************/
	/* There are a number of actions that every device	*/
	/* driver is expected to perform (even if, in some	*/
	/* cases it does nothing - just so long as it doesn't	*/
	/* crash !).  this is how the graphics engine interacts */
	/* with each device. ecah action will be documented	*/
	/* individually.					*/
	/* hooks for these actions must be set up when the	*/
	/* device is first created				*/
	/********************************************************/

	/* Device Driver Actions */

static void X11_Activate(pDevDesc dd);
static void X11_Circle(double x, double y, double r,
		       const pGEcontext gc, pDevDesc dd);
static void X11_Clip(double x0, double x1, double y0, double y1,
		     pDevDesc dd);
static void X11_Close(pDevDesc dd);
static void X11_Deactivate(pDevDesc dd);
static Rboolean X11_Locator(double *x, double *y, pDevDesc dd);
static void X11_Line(double x1, double y1, double x2, double y2,
		     const pGEcontext gc, pDevDesc dd);
static void X11_MetricInfo(int c, const pGEcontext gc,
			   double* ascent, double* descent,
			   double* width, pDevDesc dd);
static void X11_Mode(int mode, pDevDesc dd);
static void X11_NewPage(const pGEcontext gc, pDevDesc dd);
static void X11_Polygon(int n, double *x, double *y,
			const pGEcontext gc, pDevDesc dd);
static void X11_Polyline(int n, double *x, double *y,
			 const pGEcontext gc, pDevDesc dd);
static void X11_Rect(double x0, double y0, double x1, double y1,
		     const pGEcontext gc, pDevDesc dd);
static void X11_Raster(unsigned int *raster, int w, int h,
                       double x, double y, double width, double height,
                       double rot, Rboolean interpolate,
                       const pGEcontext gc, pDevDesc dd);
static SEXP X11_Cap(pDevDesc dd);
static void X11_Size(double *left, double *right,
		     double *bottom, double *top,
		     pDevDesc dd);
static double X11_StrWidth(const char *str, const pGEcontext gc, pDevDesc dd);
static void X11_Text(double x, double y, const char *str,
		     double rot, double hadj,
		     const pGEcontext gc, pDevDesc dd);
static void X11_eventHelper(pDevDesc dd, int code);

	/*************************************************/
	/* End of list of required device driver actions */
	/*************************************************/

	/* Support Routines */

static void *RLoadFont(pX11Desc, char*, int, int);
static double pixelHeight(void);
static double pixelWidth(void);
static void SetColor(unsigned int, pX11Desc);
static void SetFont(const pGEcontext, pX11Desc);
static void SetLinetype(const pGEcontext, pX11Desc);
static void X11_Close_bitmap(pX11Desc xd);
static char* translateFontFamily(char* family, pX11Desc xd);

static double RedGamma	 = 1.0;
static double GreenGamma = 1.0;
static double BlueGamma	 = 1.0;

#ifdef HAVE_WORKING_CAIRO
# include "cairoFns.c"

	/************************/
	/*        Buffering     */
	/************************/

/*
  Buffering is only implemented for the cairo-based devices.
   The original (Feb 2008) version had two types:
   - "nbcairo".  This wrote directly to a cairo_xlib_surface, xd->cs.
   - "cairo".  This wrote to a cairo_image_surface xd->cs, and copied that to 
     the cairo_xlib_surface (xd->xcs) at mode(0) calls.

   Further types were introduced (experimentally) in May 2011.  We kept:
   - "dbcairo".  Similar to cairo, but the copying is only done when needed
      based on a timer.
   Timing requires a medium-res timer. The current method is to update
   ca 100ms after the last activity (using the event loop) or at a
   mode(0) call if it is 500ms after the last update.
 */

#if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_REALTIME)) || defined(HAVE_GETTIMEOFDAY)
/* We need to avoid this in the rare case that it is only in seconds */
extern double currentTime(void); /* from datetime.c */
#else
/* Alternatively, use times() which R >= 2.14.0 requires.  This could
  conceivably wrap around, but on the sort of system where this might
  be used, clock_t is 32-bit (it is typically long or unsigned long)
  and CLK_TCK is 60-100, so it happens after many months of uptime.
*/
# include <sys/times.h>
# ifndef CLK_TCK
#   define CLK_TCK 60
# endif
static double currentTime(void)
{
    struct tms ti;
    return ((double) times(&ti))/CLK_TCK;
}
#endif

static void Cairo_update(pX11Desc xd)
{
    if(inclose || !xd || !xd->buffered || xd->holdlevel > 0) return;
    cairo_paint(xd->xcc);
    /* workaround for bug in cairo 1.12.x (PR#15168) */
    cairo_surface_flush(xd->xcs);
    if (xd->type == WINDOW) XDefineCursor(display, xd->window, arrow_cursor);
    XSync(display, 0);
    xd->last = currentTime();
}


/* 
   We record a linked list of devices which are open and double-buffered.
   The head of the list is a dummy entry to make removals the same for 
   any element.  
*/
struct xd_list {
    pX11Desc this;
   struct xd_list *next;
};

typedef struct xd_list *Xdl;
static struct xd_list xdl0;
static Xdl xdl = &xdl0;

static void CairoHandler(void)
{
    static int  buffer_lock = 0; /* reentrancy guard */
    if (!buffer_lock && xdl->next) {
	double current = currentTime();
	buffer_lock = 1;
	for(Xdl z = xdl->next; z; z = z->next) {
	    pX11Desc xd = z->this;
	    if(xd->last > xd->last_activity) continue;
	    if((current - xd->last) < xd->update_interval) continue;
	    Cairo_update(xd);
	}
	buffer_lock = 0;
    }
}

/* private hooks in sys-std.c */
extern void (* Rg_PolledEvents)(void);
extern int Rg_wait_usec;

/*
  check for updates every 50ms:
  by default the updater is only run >= 100ms after last update.
*/
#define WAIT 50000
static int timingInstalled = 0;
static void addBuffering(pX11Desc xd)
{
    Xdl xdln = (Xdl) malloc(sizeof(struct xd_list));
    xdln->this = xd;
    xdln->next = xdl->next;
    xdl->next = xdln;
    if(timingInstalled) return;
    timingInstalled = 1;
    Rg_PolledEvents = CairoHandler;
    Rg_wait_usec = WAIT;
}

static void removeBuffering(pX11Desc xd)
{
    for(Xdl z = xdl; z->next; z = z->next)
	if (z->next->this == xd) {
	    Xdl old = z->next;
	    z->next = z->next->next;
	    free(old);
	    break; 
	}
    if(xdl->next == NULL) {
	Rg_wait_usec = 0;
	timingInstalled = 0;
    }
}

static void Cairo_NewPage(const pGEcontext gc, pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    cairo_reset_clip(xd->cc);
    xd->fill = R_OPAQUE(gc->fill) ? gc->fill: xd->canvas;
    CairoColor(xd->fill, xd);
    cairo_new_path(xd->cc);
    cairo_paint(xd->cc);
    if(xd->buffered) Cairo_update(xd); 
    else XSync(display, 0);
}

static int Cairo_holdflush(pDevDesc dd, int level)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    int old = xd->holdlevel;

    if(!xd->buffered) return old;
    xd->holdlevel += level;
    if(xd->holdlevel <= 0) xd->holdlevel = 0;
//    printf("holdlevel = %d\n",  xd->holdlevel);
    /* flush if at level zero - also changes cursor */
    if(xd->holdlevel == 0) {
	if(xd->buffered) Cairo_update(xd);
	else {
	  if (xd->type == WINDOW) XDefineCursor(display, xd->window, arrow_cursor);
	    XSync(display, 0);
	}
    } else if (old == 0) {
	/* May need to flush before holding */
	if(xd->buffered > 1 && xd->last_activity > xd->last) {
	    xd->holdlevel = old;
	    Cairo_update(xd);
	    xd->holdlevel = level;
	}
	if (xd->type == WINDOW) XDefineCursor(display, xd->window, watch_cursor);
	XSync(display, 0);
    }
    return xd->holdlevel;
}
#endif /* HAVE_WORKING_CAIRO */



	/************************/
	/* X11 Color Management */
	/************************/

/* Variables Used To Store Colormap Information */
static struct { int red; int green; int blue; } RPalette[512];
static XColor XPalette[512];
static int PaletteSize;


/* Monochome Displays : Compute pixel values by converting */
/* RGB values to luminance and then thresholding. */
/* See: Foley & van Damm. */

static void SetupMonochrome(void)
{
    depth = 1;
}

static unsigned GetMonochromePixel(int r, int g, int b)
{
    if ((int)(0.299 * r + 0.587 * g + 0.114 * b) > 127)
	return (unsigned) WhitePixel(display, screen);
    else
	return (unsigned) BlackPixel(display, screen);
}


/* Grayscale Displays : Compute pixel values by converting */
/* RGB values to luminance.  See: Foley & van Damm. */

static unsigned GetGrayScalePixel(int r, int g, int b)
{
    unsigned int d, dmin = 0xFFFFFFFF;
    unsigned int dr;
    int i;
    unsigned int pixel = 0;  /* -Wall */
    int gray = (int)((0.299 * r + 0.587 * g + 0.114 * b) + 0.0001);
    for (i = 0; i < PaletteSize; i++) {
	dr = (RPalette[i].red - gray);
	d = dr * dr;
	if (d < dmin) {
	    pixel = (unsigned) XPalette[i].pixel;
	    dmin = d;
	}
    }
    return pixel;
}

static Rboolean GetGrayPalette(Display *displ, Colormap cmap, int n)
{
    int status, i, m;
    m = 0;
    i = 0;
    for (i = 0; i < n; i++) {
	RPalette[i].red	  = (unsigned short) ((i * 0xff) / (n - 1));
	RPalette[i].green = RPalette[i].red;
	RPalette[i].blue  = RPalette[i].red;
	/* Gamma correct here */
	XPalette[i].red	  = (unsigned short)((i * 0xffff) / (n - 1));
	XPalette[i].green = XPalette[i].red;
	XPalette[i].blue  = XPalette[i].red;
	status = XAllocColor(displ, cmap, &XPalette[i]);
	if (status == 0) {
	    XPalette[i].flags = 0;
	    m++;
	}
	else
	    XPalette[i].flags = DoRed|DoGreen|DoBlue;
    }
    PaletteSize = n;
    if (m > 0) {
	for (i = 0; i < PaletteSize; i++) {
	    if (XPalette[i].flags != 0)
		XFreeColors(displ, cmap, &(XPalette[i].pixel), 1, 0);
	}
	PaletteSize = 0;
	return FALSE;
    }
    else return TRUE;
}

static void SetupGrayScale(void)
{
    int res = 0, d;
    PaletteSize = 0;
    /* try for 128 grays on an 8-bit display */
    if (depth > 8) d = depth = 8; else d = depth - 1;
    /* try (256), 128, 64, 32, 16 grays */
    while (d >= 4 && !(res = GetGrayPalette(display, colormap, 1 << d)))
	d--;
    if (!res) {
	/* Can't find a sensible grayscale, so revert to monochrome */
	warning(_("cannot set grayscale: reverting to monochrome"));
	model = MONOCHROME;
	SetupMonochrome();
    }
}

/* PseudoColor Displays : There are two strategies here. */
/* 1) allocate a standard color cube and match colors */
/* within that based on (weighted) distances in RGB space. */
/* 2) allocate colors exactly as they are requested until */
/* all color cells are used.  Fail with an error message */
/* when this happens. */

static int RGBlevels[][3] = {  /* PseudoColor Palettes */
    { 8, 8, 4 },
    { 6, 7, 6 },
    { 6, 6, 6 },
    { 6, 6, 5 },
    { 6, 6, 4 },
    { 5, 5, 5 },
    { 5, 5, 4 },
    { 4, 4, 4 },
    { 4, 4, 3 },
    { 3, 3, 3 },
    { 2, 2, 2 }
};
static int NRGBlevels = sizeof(RGBlevels) / (3 * sizeof(int));


static int GetColorPalette(Display *dpy, Colormap cmap, int nr, int ng, int nb)
{
    int status, i, m, r, g, b;
    m = 0;
    i = 0;
    for (r = 0; r < nr; r++) {
	for (g = 0; g < ng; g++) {
	    for (b = 0; b < nb; b++) {
		RPalette[i].red	  = (r * 0xff) / (nr - 1);
		RPalette[i].green = (g * 0xff) / (ng - 1);
		RPalette[i].blue  = (b * 0xff) / (nb - 1);
		/* Perform Gamma Correction Here */
		XPalette[i].red	  =
		    (unsigned short)(pow(r / (nr - 1.0), RedGamma) * 0xffff);
		XPalette[i].green = 
		    (unsigned short)(pow(g / (ng - 1.0), GreenGamma) * 0xffff);
		XPalette[i].blue  = 
		    (unsigned short)(pow(b / (nb - 1.0), BlueGamma) * 0xffff);
		/* End Gamma Correction */
		status = XAllocColor(dpy, cmap, &XPalette[i]);
		if (status == 0) {
		    XPalette[i].flags = 0;
		    m++;
		}
		else
		    XPalette[i].flags = DoRed|DoGreen|DoBlue;
		i++;
	    }
	}
    }
    PaletteSize = nr * ng * nb;
    if (m > 0) {
	for (i = 0; i < PaletteSize; i++) {
	    if (XPalette[i].flags != 0)
		XFreeColors(dpy, cmap, &(XPalette[i].pixel), 1, 0);
	}
	PaletteSize = 0;
	return 0;
    }
    else
	return 1;
}

static void SetupPseudoColor(void)
{
    int i, size;
    PaletteSize = 0;
    if (model == PSEUDOCOLOR1) {
	for (i = 0; i < NRGBlevels; i++) {
	    size = RGBlevels[i][0] * RGBlevels[i][1] * RGBlevels[i][2];
	    if (size < maxcubesize && GetColorPalette(display, colormap,
				RGBlevels[i][0],
				RGBlevels[i][1],
				RGBlevels[i][2]))
		break;
	}
	if (PaletteSize == 0) {
	    warning(_("X11 driver unable to obtain color cube\n  reverting to monochrome"));
	    model = MONOCHROME;
	    SetupMonochrome();
	}
    }
    else {
	PaletteSize = 0;
    }
}

static unsigned int GetPseudoColor1Pixel(int r, int g, int b)
{
    unsigned int d, dmin = 0xFFFFFFFF;
    unsigned int dr, dg, db;
    unsigned int pixel;
    int i;
    pixel = 0;			/* -Wall */
    for (i = 0; i < PaletteSize; i++) {
	dr = (RPalette[i].red - r);
	dg = (RPalette[i].green - g);
	db = (RPalette[i].blue - b);
	d = dr * dr + dg * dg + db * db;
	if (d < dmin) {
	    pixel = (unsigned int) XPalette[i].pixel;
	    dmin = d;
	}
    }
    return pixel;
}

static unsigned int GetPseudoColor2Pixel(int r, int g, int b)
{
    int i;
    /* Search for previously allocated color */
    for (i = 0; i < PaletteSize ; i++) {
	if (r == RPalette[i].red &&
	    g == RPalette[i].green &&
	    b == RPalette[i].blue) return (unsigned int) XPalette[i].pixel;
    }
    /* Attempt to allocate a new color */
    XPalette[PaletteSize].red	= 
	(unsigned short)(pow(r / 255.0, RedGamma) * 0xffff);
    XPalette[PaletteSize].green = 
	(unsigned short)(pow(g / 255.0, GreenGamma) * 0xffff);
    XPalette[PaletteSize].blue	= 
	(unsigned short)(pow(b / 255.0, BlueGamma) * 0xffff);
    if (PaletteSize == 256 ||
	XAllocColor(display, colormap, &XPalette[PaletteSize]) == 0) {
	error(_("Error: X11 cannot allocate additional graphics colors.\n\
Consider using X11 with colortype=\"pseudo.cube\" or \"gray\"."));
    }
    RPalette[PaletteSize].red = r;
    RPalette[PaletteSize].green = g;
    RPalette[PaletteSize].blue = b;
    PaletteSize++;
    return (unsigned int)XPalette[PaletteSize - 1].pixel;
}

static unsigned int GetPseudoColorPixel(int r, int g, int b)
{
    if (model == PSEUDOCOLOR1)
	return GetPseudoColor1Pixel(r, g, b);
    else
	return GetPseudoColor2Pixel(r, g, b);
}

/* Truecolor Displays : Allocate the colors as they are requested */

static unsigned int RMask, RShift;
static unsigned int GMask, GShift;
static unsigned int BMask, BShift;

static void SetupTrueColor(void)
{
    RMask = (unsigned int)visual->red_mask;
    GMask = (unsigned int)visual->green_mask;
    BMask = (unsigned int)visual->blue_mask;
    RShift = 0; while ((RMask & 1) == 0) { RShift++; RMask >>= 1; }
    GShift = 0; while ((GMask & 1) == 0) { GShift++; GMask >>= 1; }
    BShift = 0; while ((BMask & 1) == 0) { BShift++; BMask >>= 1; }
}

static unsigned GetTrueColorPixel(int r, int g, int b)
{
    r = (int)(pow((r / 255.0), RedGamma) * 255);
    g = (int)(pow((g / 255.0), GreenGamma) * 255);
    b = (int)(pow((b / 255.0), BlueGamma) * 255);
    return
	(((r * RMask) / 255) << RShift) |
	(((g * GMask) / 255) << GShift) |
	(((b * BMask) / 255) << BShift);
}

/* Interface for General Visual */

static unsigned int GetX11Pixel(int r, int g, int b)
{
    switch(model) {
    case MONOCHROME:
	return GetMonochromePixel(r, g, b);
    case GRAYSCALE:
	return GetGrayScalePixel(r, g, b);
    case PSEUDOCOLOR1:
    case PSEUDOCOLOR2:
	return GetPseudoColorPixel(r, g, b);
    case TRUECOLOR:
	return GetTrueColorPixel(r, g, b);
    default:
	printf("Unknown Visual\n");
    }
    return 0;
}

static void FreeX11Colors(void)
{
    int i;
    if (model == PSEUDOCOLOR2) {
	for (i = 0; i < PaletteSize; i++)
	    XFreeColors(display, colormap, &(XPalette[i].pixel), 1, 0);
	PaletteSize = 0;
    }
}

static Rboolean SetupX11Color(void)
{
    if (depth <= 1) {
	/* On monchome displays we must use black/white */
	model = MONOCHROME;
	SetupMonochrome();
    }
    else if (Vclass ==	StaticGray || Vclass == GrayScale) {
	if (model == MONOCHROME)
	    SetupMonochrome();
	else {
	    model = GRAYSCALE;
	    SetupGrayScale();
	}
    }
    else if (Vclass == StaticColor) {
	/* FIXME : Currently revert to mono. */
	/* Should do the real thing. */
	model = MONOCHROME;
	SetupMonochrome();
    }
    else if (Vclass ==	PseudoColor) {
	if (model == MONOCHROME)
	    SetupMonochrome();
	else if (model == GRAYSCALE)
	    SetupGrayScale();
	else {
	    if (model == TRUECOLOR)
		model = PSEUDOCOLOR2;
	    SetupPseudoColor();
	}
    }
    else if (Vclass == TrueColor) {
	if (model == MONOCHROME)
	    SetupMonochrome();
	else if (model == GRAYSCALE)
	    SetupGrayScale();
	else if (model == PSEUDOCOLOR1 || model == PSEUDOCOLOR2)
	    SetupPseudoColor();
	else
	    SetupTrueColor();
    }
    else if (Vclass == DirectColor) {
	/* FIXME : Currently revert to mono. */
	/* Should do the real thing. */
	model = MONOCHROME;
	SetupMonochrome();
    }
    else {
	printf("Unknown Visual\n");
	return FALSE;
    }
    return TRUE;
}

	/* Pixel Dimensions (Inches) */


static double pixelWidth(void)
{
    double width, widthMM;
    width = DisplayWidth(display, screen);
    widthMM = DisplayWidthMM(display, screen);
    return ((double)widthMM / (double)width) / MM_PER_INCH;
}

static double pixelHeight(void)
{
    double height, heightMM;
    height = DisplayHeight(display, screen);
    heightMM = DisplayHeightMM(display, screen);
    return ((double)heightMM / (double)height) / MM_PER_INCH;
}

static void handleEvent(XEvent event)
{
    if (event.xany.type == Expose) {
	/* ----- window repaint ------ */
	while (XCheckTypedWindowEvent(display, event.xexpose.window, Expose, &event));
	if (inclose) return;
	if (event.xexpose.count != 0) return;
	caddr_t temp;
	XFindContext(display, event.xexpose.window, devPtrContext, &temp);
	pDevDesc dd = (pDevDesc) temp;
	pGEDevDesc gdd = desc2GEDesc(dd);
	if(gdd->dirty) {
#ifdef HAVE_WORKING_CAIRO
	    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
	    /* We can use the buffered copy where we have it */ 
	    if(xd->buffered == 1) {
		cairo_paint(xd->xcc);
		/* workaround for bug in cairo 1.12.x (PR#15168) */
		cairo_surface_flush(xd->xcs);
	    } else if (xd->buffered > 1)
		/* rely on timer to repaint eventually */
		xd->last_activity = currentTime();
	    else
#endif
		GEplayDisplayList(gdd);
	    XSync(display, 0);
	}
    } else if (event.type == ConfigureNotify) {
	while (XCheckTypedEvent(display, ConfigureNotify, &event)) ;
	if (inclose) return;
	caddr_t temp;
	XFindContext(display, event.xconfigure.window, devPtrContext, &temp);
	pDevDesc dd = (pDevDesc) temp;
	pX11Desc xd = (pX11Desc) dd->deviceSpecific;
	if (xd->windowWidth != event.xconfigure.width ||
	    xd->windowHeight != event.xconfigure.height) {

	    /* ----- window resize ------ */

	    xd->windowWidth = event.xconfigure.width;
	    xd->windowHeight = event.xconfigure.height;
#if defined HAVE_WORKING_CAIRO
	    if(xd->useCairo) {
		if(xd->buffered) {
		    cairo_surface_destroy(xd->cs); xd->cs = NULL;
		    cairo_destroy(xd->cc); xd->cc = NULL;
		    cairo_xlib_surface_set_size(xd->xcs, xd->windowWidth,
						    xd->windowHeight);
		    xd->cs = 
			cairo_image_surface_create(CAIRO_FORMAT_RGB24,
						   xd->windowWidth,
						   xd->windowHeight);
		    cairo_status_t res = cairo_surface_status(xd->cs);
		    if (res != CAIRO_STATUS_SUCCESS) {
			warning("cairo error '%s'", 
				cairo_status_to_string(res));
			error("fatal error on resize: please shut down the device");
		    }
		    xd->cc = cairo_create(xd->cs);
		    cairo_set_antialias(xd->cc, xd->antialias);
		    cairo_set_source_surface (xd->xcc, xd->cs, 0, 0);
		} else { /* not buffered */
		    cairo_xlib_surface_set_size(xd->cs, xd->windowWidth,
						xd->windowHeight);
		    cairo_reset_clip(xd->cc);
		}
	    }
#endif
	    dd->size(&(dd->left), &(dd->right), &(dd->bottom), &(dd->top), dd);	
	    /* gobble Expose events; we'll redraw anyway */
	    while (XCheckTypedWindowEvent(display, event.xexpose.window, Expose, &event));
	    pGEDevDesc gdd = desc2GEDesc(dd);
	    if(gdd->dirty) {
		GEplayDisplayList(gdd);
		XSync(display, 0);
	    }
	}
    } else if ((event.type == ClientMessage) &&
	     (event.xclient.message_type == _XA_WM_PROTOCOLS)) {
	if (!inclose && event.xclient.data.l[0] == protocol) {
	    caddr_t temp;
	    XFindContext(display, event.xclient.window, devPtrContext, &temp);
	    killDevice(ndevNumber((pDevDesc) temp));
	}
    }
}

static void R_ProcessX11Events(void *data)
{
    XEvent event;

    while (!R_isForkedChild && displayOpen && XPending(display)) {
	XNextEvent(display, &event);
	/* printf("%i\n",event.type); */
	handleEvent(event);
    }
}


	/************************/
	/* X11 Font Management  */
	/************************/

static char *fontname = "-adobe-helvetica-%s-%s-*-*-%d-*-*-*-*-*-*-*";
static char *symbolname	 = "-adobe-symbol-medium-r-*-*-%d-*-*-*-*-*-*-*";

static char *slant[]  = {"r", "o"};
static char *weight[] = {"medium", "bold"};

/* Bitmap of the Adobe design sizes */

static unsigned int adobe_sizes = 0x0403165D;

#define MAXFONTS 64
#define CLRFONTS 16 /* Number to free when cache runs full */

typedef struct {
    char family[500];
    int face, size;
    R_XFont *font;
} cacheentry;

static cacheentry fontcache[MAXFONTS];
static int nfonts = 0;
static int force_nonscalable = 0; /* for testing */

#define ADOBE_SIZE(I) ((I) > 7 && (I) < 35 && (adobe_sizes & (1<<((I)-8))))
#define SMALLEST 2


static R_XFont *R_XLoadQueryFont(Display *display, char *name)
{
    R_XFont *tmp;
    tmp = (R_XFont *) malloc(sizeof(R_XFont));
    tmp->type = One_Font;
    tmp->font = XLoadQueryFont(display, name);
    if(tmp->font)
	return tmp;
    else {
	free(tmp);
	return NULL;
    }
}

static void R_XFreeFont(Display *display, R_XFont *font)
{
    if(font->type == Font_Set) XFreeFontSet(display, font->fontset);
    else XFreeFont(display, font->font);
    free(font);
}


/*
 * Can't load Symbolfont to XFontSet!!
 */
static R_XFont *R_XLoadQueryFontSet(Display *display,
				    const char *fontset_name)
{
    R_XFont *tmp = (R_XFont *) malloc(sizeof(R_XFont));
    XFontSet fontset;
    int  /*i,*/ missing_charset_count;
    char **missing_charset_list, *def_string;

#ifdef DEBUG_X11
    printf("loading fontset %s\n", fontset_name);
#endif
    fontset = XCreateFontSet(display, fontset_name, &missing_charset_list,
			     &missing_charset_count, &def_string);
    if(!fontset) {
	free(tmp);
	return NULL;
    }
    if (missing_charset_count) {
#ifdef DEBUG_X11
	int i;
	for(i = 0; i < missing_charset_count; i++)
	   warning("font for charset %s is lacking.", missing_charset_list[i]);
	XFreeStringList(missing_charset_list);
#endif
    }
    tmp->type = Font_Set;
    tmp->fontset = fontset;
    return tmp;
}


static void *RLoadFont(pX11Desc xd, char* family, int face, int size)
{
    /* size is in points here */
    int pixelsize, i, dpi;
    cacheentry *f;
    char buf[BUFSIZ];
    char buf1[BUFSIZ];
    R_XFont *tmp = NULL;

#ifdef DEBUG_X11
    printf("trying face %d size %d\n", face, size);
#endif

    if (size < SMALLEST) size = SMALLEST;
    face--;

    if(xd->type == PNG || xd->type == JPEG ||
       xd->type == TIFF || xd->type == BMP) {
	dpi = (xd->res_dpi > 0) ? (int)(xd->res_dpi + 0.5) : 72;
    } else {
	dpi = (int)(1./pixelHeight() + 0.5);
    }

    if(abs(dpi - 75) < 5) {
	/* use pointsize as pixel size */
    } else if(abs(dpi - 100) < 5) {
    /* Here's a 1st class fudge: make sure that the Adobe design sizes
       8, 10, 11, 12, 14, 17, 18, 20, 24, 25, 34 can be obtained via
       an integer "size" at 100 dpi, namely 6, 7, 8, 9, 10, 12, 13,
       14, 17, 18, 24 points. It's almost y = x * 100/72, but not
       quite. The constants were found using lm(). --pd */
	size = (int) R_rint(size * 1.43 - 0.4);
    } else size = (int) R_rint(size * dpi/72);

    /* search fontcache */
    for ( i = nfonts ; i-- ; ) {
	f = &fontcache[i];
	if ( strcmp(f->family, family) == 0 &&
	     f->face == face &&
	     f->size == size )
	    return f->font;
    }

    /* 'size' is the requested size, 'pixelsize'  the size of the
       actually allocated font*/
    pixelsize = size;

    /*
     * The symbol font face is a historical oddity
     * Always use a standard font for font face 5
     */
    if (face == SYMBOL_FONTFACE - 1) /* NB: face-- above */
	sprintf(buf, xd->symbolfamily,  pixelsize);
    else
      if (mbcslocale && *slant[(face & 2) >> 1] == 'o') {
	sprintf(buf, family, weight[face & 1], slant[(face & 2) >> 1],
		pixelsize);
	sprintf(buf1, family, weight[face & 1], "i",  pixelsize);
	strcat(buf,",");
	strcat(buf,buf1);
      } else
	  sprintf(buf, family, weight[face & 1], slant[(face & 2) >> 1],
		  pixelsize);
#ifdef DEBUG_X11
    Rprintf("loading:\n%s\n",buf);
#endif
    if (!mbcslocale || face == SYMBOL_FONTFACE - 1)
      tmp = R_XLoadQueryFont(display, buf);
    else
      tmp = R_XLoadQueryFontSet(display, buf);

#ifdef DEBUG_X11
    if (tmp) Rprintf("success\n"); else Rprintf("failure\n");
#endif
    /*
     * IF can't find the font specified then
     * go to great lengths to find something else to use.
     */
    if (!tmp || (force_nonscalable && !ADOBE_SIZE(size)) ){
	static int near[]=
	  {14,14,14,17,17,18,20,20,20,20,24,24,24,25,25,25,25};
	/* 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29  */

	/* If ADOBE_SIZE(pixelsize) is true at this point then
	   the user's system does not have the standard ADOBE font set
	   so we just have to use a "fixed" font.
	   If we can't find a "fixed" font then something is seriously
	   wrong */
	if ( ADOBE_SIZE(pixelsize) ) {
	    if(tmp)
		R_XFreeFont(display, tmp);
	    if(mbcslocale)
		tmp = (void*) R_XLoadQueryFontSet(display,
		   "-*-fixed-medium-r-*--13-*-*-*-*-*-*-*");
	    else
		tmp = (void*) R_XLoadQueryFont(display, "fixed");

	    if (tmp)
		return tmp;
	    else
		error(_("could not find any X11 fonts\nCheck that the Font Path is correct."));
	}

	if ( pixelsize < 8 )
	    pixelsize = 8;
	else if (pixelsize == 9)
	    pixelsize = 8;
	else if (pixelsize < 30) /* must be at least 13 */
	    pixelsize = near[size-13];
	else
	    pixelsize = 34;


	if (face == SYMBOL_FONTFACE - 1)
	    sprintf(buf, symbolname, pixelsize);
	else
	    sprintf(buf, fontname,
		    weight[face & 1],
		    slant[(face & 2) >> 1 ],  pixelsize);
#ifdef DEBUG_X11
	Rprintf("loading:\n%s\n",buf);
#endif
	if (!mbcslocale || face == SYMBOL_FONTFACE - 1)
	    tmp = R_XLoadQueryFont(display, buf);
	else
	    tmp = R_XLoadQueryFontSet(display, buf);
#ifdef DEBUG_X11
	if (tmp) Rprintf("success\n"); else Rprintf("failure\n");
#endif
    }
    if(!tmp && size > 24) {
	/* final try, size 24 */
	pixelsize = 24;
	if (face == 4)
	    sprintf(buf, symbolname, 24);
	else
	    sprintf(buf, fontname,
		    weight[face & 1],
		    slant[(face & 2) >> 1 ],  24);
#ifdef DEBUG_X11
	Rprintf("loading:\n%s\n",buf);
#endif

	if (!mbcslocale || face == SYMBOL_FONTFACE - 1)
	    tmp = R_XLoadQueryFont(display, buf);
	else
	    tmp = R_XLoadQueryFontSet(display, buf);

#ifdef DEBUG_X11
	if (tmp) Rprintf("success\n"); else Rprintf("failure\n");
#endif
    }

    if (tmp){
	f = &fontcache[nfonts++];
	strcpy(f->family, family);
	f->face = face;
	f->size = size;
	f->font = tmp;
	if (fabs( (pixelsize - size)/(double)size ) > 0.1)
	    warning(_("X11 used font size %d when %d was requested"),
		    pixelsize, size);
    }
    if (nfonts == MAXFONTS) /* make room in the font cache */
    {
	for (i = 0 ; i < CLRFONTS ; i++)
	      R_XFreeFont(display, fontcache[i].font);
	for (i = CLRFONTS ; i < MAXFONTS ; i++)
	    fontcache[i - CLRFONTS] = fontcache[i];
	nfonts -= CLRFONTS;
    }
    return tmp;
}


static void SetFont(const pGEcontext gc, pX11Desc xd)
{
    R_XFont *tmp;
    char *family = translateFontFamily(gc->fontfamily, xd);
    /* size is in points here */
    int size = (int)(gc->cex * gc->ps + 0.5), face = gc->fontface;

    if (face < 1 || face > 5) face = 1;

    if (size != xd->fontsize	|| face != xd->fontface ||
	strcmp(family, xd->fontfamily) != 0) {

	tmp = RLoadFont(xd, family, face, size);
	if(tmp) {
	    xd->font = tmp;
	    strcpy(xd->fontfamily, family);
	    xd->fontface = face;
	    xd->fontsize = size;
	} else
	    error(_("X11 font %s, face %d at size %d could not be loaded"),
		  family, face, size);
    }
}

static void CheckAlpha(int color, pX11Desc xd)
{
    unsigned int alpha = R_ALPHA(color);
    if (alpha > 0 && alpha < 255 && !xd->warn_trans) {
	warning(_("semi-transparency is not supported on this device: reported only once per page"));
	xd->warn_trans = TRUE;
    }
}

static void SetColor(unsigned int color, pX11Desc xd)
{
    if (color != xd->col) {
	int col = GetX11Pixel(R_RED(color), R_GREEN(color), R_BLUE(color));
	xd->col = color;
	XSetState(display, xd->wgc, col, whitepixel, GXcopy, AllPlanes);
    }
}

static int gcToX11lend(R_GE_lineend lend) {
    int newend = CapRound; /* -Wall */
    switch (lend) {
    case GE_ROUND_CAP:
	newend = CapRound;
	break;
    case GE_BUTT_CAP:
	newend = CapButt;
	break;
    case GE_SQUARE_CAP:
	newend = CapProjecting;
	break;
    default:
	error(_("invalid line end"));
    }
    return newend;
}

static int gcToX11ljoin(R_GE_linejoin ljoin) {
    int newjoin = JoinRound; /* -Wall */
    switch (ljoin) {
    case GE_ROUND_JOIN:
	newjoin = JoinRound;
	break;
    case GE_MITRE_JOIN:
	newjoin = JoinMiter;
	break;
    case GE_BEVEL_JOIN:
	newjoin = JoinBevel;
	break;
    default:
	error(_("invalid line join"));
    }
    return newjoin;
}

/* --> See "Notes on Line Textures" in GraphicsEngine.h
 *
 *	27/5/98 Paul - change to allow lty and lwd to interact:
 *	the line texture is now scaled by the line width so that,
 *	for example, a wide (lwd=2) dotted line (lty=2) has bigger
 *	dots which are more widely spaced.  Previously, such a line
 *	would have "dots" which were wide, but not long, nor widely
 *	spaced.
 */

/* Not at all clear the optimization here is worth it */
static void SetLinetype(const pGEcontext gc, pX11Desc xd)
{
    int i, newlty, newlend, newljoin;
    double newlwd;

    newlty = gc->lty;
    newlwd = gc->lwd;
    if (newlwd < 1)/* not less than 1 pixel */
	newlwd = 1;
    if (newlty != xd->lty || newlwd != xd->lwd ||
	gc->lend != xd->lend || gc->ljoin != xd->ljoin) {
	xd->lty = newlty;
	xd->lwd = newlwd;
	xd->lend = gc->lend;
	xd->ljoin = gc->ljoin;
	newlend = gcToX11lend(gc->lend);
	newljoin = gcToX11ljoin(gc->ljoin);
	if (newlty == 0 || newlty == NA_INTEGER) {/* special hack for lty = 0 -- only for X11 */
	    XSetLineAttributes(display, xd->wgc,
			       (int)(newlwd*xd->lwdscale+0.5),
			       LineSolid, newlend, newljoin);
	} else {
	    static char dashlist[8];
	    for(i = 0 ; i < 8 && (newlty != 0); i++) {
		int j = newlty & 15;
		if (j == 0) j = 1; /* Or we die with an X Error */
		/* scale line texture for line width */
		j = (int)(j*newlwd*xd->lwdscale+0.5);
		/* make sure that scaled line texture */
		/* does not exceed X11 storage limits */
		if (j > 255) j = 255;
		dashlist[i] = (char) j;
		newlty >>= 4;
	    }
	    /* NB if i is odd the pattern will be interpreted as
	       the original pattern concatenated with itself */
	    XSetDashes(display, xd->wgc, 0, dashlist, i);
	    XSetLineAttributes(display, xd->wgc,
			       (int)(newlwd*xd->lwdscale+0.5),
			       LineOnOffDash, newlend, newljoin);
	}
    }
}

/* Error handling. FIXME: This is rather sloppy; we ought to respect
   any 3rd party handlers by checking whether dsp is "our" display and
   calling the previous handler otherwise. */

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_X11IOErrSimple(Display *dsp)
{
    char *dn = XDisplayName(dspname);
    strcpy(dspname, "");
    error(_("X11 I/O error while opening X11 connection to '%s'"), dn);
}

static int NORET R_X11IOErr(Display *dsp)
{
    int fd = ConnectionNumber(display);
    /*
    while (nfonts--)  R_XFreeFont(display, fontcache[nfonts].font);
    nfonts = 0;
    */
    removeInputHandler(&R_InputHandlers,
		       getInputHandler(R_InputHandlers,fd));
    /*
    XCloseDisplay(display);
    displayOpen = FALSE;
    strcpy(dspname, "");
    */
    error(_("X11 fatal IO error: please save work and shut down R"));
}

#define USE_Xt 1

#ifdef USE_Xt
#include <X11/StringDefs.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(XtNbackground, XtCBackground, background, "XtDefaultBackground"),
    rstr(XtNgeometry, XtCGeometry, geometry, NULL),
};

static const int x_resource_count = XtNumber(x_resources);

static String x_fallback_resources[] = {
    (String) "R_x11*Background: white",
    NULL
};
#endif

Rboolean
X11_Open(pDevDesc dd, pX11Desc xd, const char *dsp,
	 double w, double h, double gamma_fac, X_COLORTYPE colormodel,
	 int maxcube, int bgcolor, int canvascolor, int res,
	 int xpos, int ypos)
{
    /* if we have to bail out with "error", then must free(dd) and free(xd) */
    /* That means the *caller*: the X11DeviceDriver code frees xd, for example */

    XEvent event;
    int iw, ih, blackpixel;
    X_GTYPE type;
    const char *p = dsp;
    XGCValues gcv;
    XSizeHints *hint;

    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 (!strncmp(dsp, "png::", 5)) {
#ifndef HAVE_PNG
	warning(_("no png support in this version of R"));
	return FALSE;
#else
	char buf[PATH_MAX]; /* allow for pageno formats */
	FILE *fp;
	if(strlen(dsp+5) >= PATH_MAX)
	    error(_("filename too long in png() call"));
	strcpy(xd->filename, dsp+5);
	snprintf(buf, PATH_MAX, dsp+5, 1); /* page 1 to start */
	if (!(fp = R_fopen(R_ExpandFileName(buf), "w"))) {
	    warning(_("could not open PNG file '%s'"), buf);
	    return FALSE;
	}
	xd->fp = fp;
	type = PNG;
	p = "";
	xd->res_dpi = res; /* place holder */
	dd->displayListOn = FALSE;
#endif
    }
    else if (!strncmp(dsp, "jpeg::", 6)) {
#ifndef HAVE_JPEG
	warning(_("no jpeg support in this version of R"));
	return FALSE;
#else
	char buf[PATH_MAX]; /* allow for pageno formats */
	char tmp[PATH_MAX], *pp;
	FILE *fp;
	strcpy(tmp, dsp+6);
	pp = strchr(tmp, ':'); *pp='\0';
	xd->quality = atoi(dsp+6);
	if(strlen(pp+1) >= PATH_MAX)
	    error(_("filename too long in jpeg() call"));
	strcpy(xd->filename, pp+1);
	snprintf(buf, PATH_MAX, pp+1, 1); /* page 1 to start */
	if (!(fp = R_fopen(R_ExpandFileName(buf), "w"))) {
	    warning(_("could not open JPEG file '%s'"), buf);
	    return FALSE;
	}
	xd->fp = fp;
	type = JPEG;
	p = "";
	xd->res_dpi = res; /* place holder */
	dd->displayListOn = FALSE;
#endif
    }
    else if (!strncmp(dsp, "tiff::", 5)) {
#ifndef HAVE_TIFF
	warning(_("no tiff support in this version of R"));
	return FALSE;
#else
	char tmp[PATH_MAX], *pp;
	strcpy(tmp, dsp+6);
	pp = strchr(tmp, ':'); *pp='\0';
	xd->quality = atoi(dsp+6);
	if(strlen(pp+1) >= PATH_MAX)
	    error(_("filename too long in tiff() call"));
	strcpy(xd->filename, pp+1);
	xd->fp = NULL;
	type = TIFF;
	p = "";
	xd->res_dpi = res; /* place holder */
	dd->displayListOn = FALSE;
#endif
    } else if (!strncmp(dsp, "bmp::", 5)) {
	char buf[PATH_MAX]; /* allow for pageno formats */
	FILE *fp;
	if(strlen(dsp+5) >= PATH_MAX)
	    error(_("filename too long in bmp() call"));
	strcpy(xd->filename, dsp+5);
	snprintf(buf, PATH_MAX, dsp+5, 1); /* page 1 to start */
	if (!(fp = R_fopen(R_ExpandFileName(buf), "w"))) {
	    warning(_("could not open BMP file '%s'"), buf);
	    return FALSE;
	}
	xd->fp = fp;
	type = BMP;
	p = "";
	xd->res_dpi = res; /* place holder */
	dd->displayListOn = FALSE;
    } else if (!strcmp(dsp, "XImage")) {
	type = XIMAGE;
	xd->fp = NULL;
	p = "";
    }
    else type = WINDOW;
    xd->type = type;

    /* If there is no server connection, establish one and */
    /* initialize the X11 device driver data structures. */

    if (!displayOpen) {
	/* Bill Dunlap sees an error when tunneling to a non-existent
	   X11 connection that BDR cannot reproduce.  We leave a handler set
	   if we get an error, but that is rare.
	*/
	X11IOhandler old;
	strncpy(dspname, p, 101);
	dspname[100] = '\0';
	old = XSetIOErrorHandler(R_X11IOErrSimple);
	if ((display = XOpenDisplay(p)) == NULL) {
	    XSetIOErrorHandler(old);
	    warning(_("unable to open connection to X11 display '%s'"), p);
	    return FALSE;
	}
	XSetIOErrorHandler(old);
	Rf_setX11Display(display, gamma_fac, colormodel, maxcube, TRUE);
	displayOpen = TRUE;
	if(xd->handleOwnEvents == FALSE)
	    addInputHandler(R_InputHandlers, ConnectionNumber(display),
			    R_ProcessX11Events, XActivity);
    } else if(strcmp(p, dspname))
	warning(_("ignoring 'display' argument as an X11 device is already open"));
    whitepixel = GetX11Pixel(R_RED(canvascolor), R_GREEN(canvascolor),
			     R_BLUE(canvascolor));
    blackpixel = GetX11Pixel(0, 0, 0);
#ifdef HAVE_WORKING_CAIRO
    if(xd->useCairo && Vclass != TrueColor) {
	warning(_("cairo-based types may only work correctly on TrueColor visuals"));
    }
#endif

    /* Foreground and Background Colors */

    xd->fill = bgcolor; /* was transparent */
    xd->col = R_RGB(0, 0, 0);
    xd->canvas = canvascolor;
    if(type == JPEG && !R_OPAQUE(xd->canvas)) {
	warning(_("jpeg() does not support transparency: using white bg"));
	xd->canvas = 0xffffff;
    }
    if(type > WINDOW) xd->fill = xd->canvas;


    /* Try to create a simple window. */
    /* We want to know about exposures */
    /* and window-resizes and locations. */

    /*
     * <MBCS-FIXED>: R on gnome window manager task-bar button see?
     * I try it.
     * A button such as, maximization disappears
     * unless I give Hint for clear statement in
     * gnome window manager.
     */

    memset(&attributes, 0, sizeof(attributes));
    attributes.background_pixel = whitepixel;
    attributes.border_pixel = blackpixel;
    attributes.backing_store = NotUseful;
    attributes.event_mask = ButtonPressMask 
      | PointerMotionMask 
      | PointerMotionHintMask
      | ButtonReleaseMask
      | ExposureMask
      | StructureNotifyMask
      | KeyPressMask;


    if (type == WINDOW) {
	int alreadyCreated = (xd->window != (Window)NULL);
	if(alreadyCreated == 0) {
	    xd->windowWidth = iw = (int)((ISNA(w)?7:w)/pixelWidth());
	    xd->windowHeight = ih = (int)((ISNA(h)?7:h)/pixelHeight());

	    hint = XAllocSizeHints();
	    if(xpos == NA_INTEGER)
		hint->x = numX11Devices*20 %
		    ( DisplayWidth(display, screen) - iw - 10 );
	    else hint->x = (xpos >= 0) ? xpos :
		DisplayWidth(display, screen) - iw + xpos;

	    if(ypos == NA_INTEGER)
		hint->y = numX11Devices*20 %
		    ( DisplayHeight(display, screen) + ih - 10 );
	    else hint->y = (ypos >= 0)? ypos :
		DisplayHeight(display, screen) - iw - ypos;
	    hint->width  = iw;
	    hint->height = ih;
	    hint->flags  = PPosition | PSize;
#ifdef USE_Xt
	    {
		XtAppContext app_con;
		Widget toplevel;
		Display *xtdpy;
		int zero = 0;
		gx_device_X xdev;

		XtToolkitInitialize();

		app_con = XtCreateApplicationContext();
		XtAppSetFallbackResources(app_con, x_fallback_resources);
		xtdpy = XtOpenDisplay(app_con, dspname, "r_x11", "R_x11",
				      NULL, 0, &zero, NULL);
		if(xtdpy) {
		    toplevel = XtAppCreateShell(NULL, "R_x11",
						applicationShellWidgetClass,
						xtdpy, NULL, 0);
		    XtGetApplicationResources(toplevel, (XtPointer) &xdev,
					      x_resources,
					      x_resource_count,
					      NULL, 0);
		    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(display, DefaultScreen(display),
					      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;
			/* Restore user-specified settings */
			if(xpos != NA_INTEGER)
			    hint->x = (xpos >= 0) ? xpos :
				DisplayWidth(display, screen) - iw + xpos;
			if(ypos != NA_INTEGER)
			    hint->y = (ypos >= 0)? ypos :
				DisplayHeight(display, screen) - iw - ypos;
			if(!ISNA(w)) hint->width = iw;
			if(!ISNA(h)) hint->height = ih;
		    }
		    XtDestroyWidget(toplevel);
		    XtCloseDisplay(xtdpy);
		} else {
		    warning(_("unable to obtain information on display '%s'"),
			    dsp);
		}
		XtDestroyApplicationContext(app_con);
	    }
#endif
	    xd->windowWidth = hint->width;
	    xd->windowHeight = hint->height;
	    /*printf("x = %d, y = %d\n", hint->x, hint->y);*/
	    xd->window = XCreateSimpleWindow(display,
					     rootwin,
					     hint->x,hint->y,
					     hint->width, hint->height,
					     1,
					     blackpixel,
					     whitepixel);
	    if (xd->window == 0 ) {
	      XFree(hint);
	      warning(_("unable to create X11 window"));
	      return FALSE;
	    }
	    XSetWMNormalHints(display, xd->window, hint);
	    XFree(hint);
	    XChangeWindowAttributes(display, xd->window,
				    CWEventMask | CWBackPixel |
				    CWBorderPixel | CWBackingStore,
				    &attributes);

	    XStoreName(display, xd->window, xd->title);

	    /* See (PR#14588) */
	    XClassHint *chint;
	    chint = XAllocClassHint();
	    if (chint) {
		chint->res_name = "r_x11";
		chint->res_class = "R_x11";
		XSetClassHint(display, xd->window, chint);
	    	XFree(chint);
	    }

            /* set window icon */
            XChangeProperty(display, xd->window,
                            XInternAtom(display, "_NET_WM_ICON", False),
                            XInternAtom(display, "CARDINAL", False), 32,
                            PropModeReplace,
                            (const unsigned char*) rlogo_icon, 2 + 99*77);

	    /* set up protocols so that window manager sends */
	    /* me an event when user "destroys" window */
	    _XA_WM_PROTOCOLS = XInternAtom(display, "WM_PROTOCOLS", 0);
	    protocol = XInternAtom(display, "WM_DELETE_WINDOW", 0);
	    XSetWMProtocols(display, xd->window, &protocol, 1);

	    if(!arrow_cursor)
		arrow_cursor = XCreateFontCursor(display, XC_left_ptr) ;
	    if(!cross_cursor)
		cross_cursor = XCreateFontCursor(display, XC_crosshair);
	    if(!watch_cursor)
		watch_cursor = XCreateFontCursor(display, XC_watch) ;
	    if(xd->type==WINDOW) XDefineCursor(display, xd->window, arrow_cursor);

#ifdef HAVE_WORKING_CAIRO
	    if(xd->useCairo) {
		cairo_status_t res;
		if(xd->buffered) {
		    xd->xcs = 
			cairo_xlib_surface_create(display, xd->window,
						  visual,
						  xd->windowWidth,
						  xd->windowHeight);
		    res = cairo_surface_status(xd->xcs);
		    if (res != CAIRO_STATUS_SUCCESS) {
			warning("cairo error '%s'",
				cairo_status_to_string(res));
			/* bail out */
			return FALSE;
		    }
		    xd->xcc = cairo_create(xd->xcs);
		    res = cairo_status(xd->xcc);
		    if (res != CAIRO_STATUS_SUCCESS) {
			warning("cairo error '%s'", 
				cairo_status_to_string(res));
			cairo_surface_destroy(xd->xcs);
			/* bail out */
			return FALSE;
		    }
		    xd->cs = 
			cairo_image_surface_create(CAIRO_FORMAT_RGB24,
						   xd->windowWidth,
						   xd->windowHeight);
		    cairo_set_source_surface (xd->xcc, xd->cs, 0, 0);
		    if(xd->buffered > 1) addBuffering(xd);
		} else /* non-buffered */
		    xd->cs = 
			cairo_xlib_surface_create(display, xd->window,
						  visual,
						  xd->windowWidth,
						  xd->windowHeight);

		res = cairo_surface_status(xd->cs);
		if (res != CAIRO_STATUS_SUCCESS) {
		    warning("cairo error '%s'", cairo_status_to_string(res));
		    /* bail out */
		    if(xd->xcs) cairo_surface_destroy(xd->xcs);
		    if(xd->xcc) cairo_destroy(xd->xcc);
		    return FALSE;
		}
		xd->cc = cairo_create(xd->cs);
		res = cairo_status(xd->cc);
		if (res != CAIRO_STATUS_SUCCESS) {
		    warning("cairo error '%s'", cairo_status_to_string(res));
		    cairo_surface_destroy(xd->cs);
		    /* bail out */
		    if(xd->xcs) cairo_surface_destroy(xd->xcs);
		    if(xd->xcc) cairo_destroy(xd->xcc);
		    return FALSE;
		}
		cairo_set_operator(xd->cc, CAIRO_OPERATOR_OVER);
		cairo_set_antialias(xd->cc, xd->antialias);
		CairoColor(xd->canvas, xd);
		cairo_new_path(xd->cc);
		cairo_paint(xd->cc);
	    }
#endif
	}
	/* Save the pDevDesc with the window for event dispatching */
	XSaveContext(display, xd->window, devPtrContext, (caddr_t) dd);

	/* Map the window */
	if(alreadyCreated == 0) {
	    XSelectInput(display, xd->window,
			 ExposureMask | ButtonPressMask | StructureNotifyMask 
			 | ButtonReleaseMask | PointerMotionMask  
                         | PointerMotionHintMask | KeyPressMask);
	    XMapWindow(display, xd->window);
	    XSync(display, 0);

	    /* Gobble MapNotify events */

	    while ( XPeekEvent(display, &event),
		    !XCheckTypedEvent(display, MapNotify, &event))
		;
	    /* XNextEvent(display, &event);
	       if (event.xany.type == Expose) {
	       while (event.xexpose.count)
	       XNextEvent(display, &event);
	       }
	    */
	}
    } else { /* PIXMAP */
	xd->windowWidth = iw = (int) w;
	xd->windowHeight = ih = (int) h;
	if (iw < 20 && ih < 20)
	    warning(_("'width=%d, height=%d' are unlikely values in pixels"),
		    iw, ih);
	if ((xd->window = XCreatePixmap(
	    display, rootwin,
	    iw, ih, DefaultDepth(display, screen))) == 0) {
	    warning(_("unable to create pixmap"));
	    return FALSE;
	}
	/* Save the pDevDesc with the window for event dispatching */
	/* Is this needed? */
	XSaveContext(display, xd->window, devPtrContext, (caddr_t) dd);
	xd->npages = 0;
    }

    /* Set the graphics context */

    gcv.arc_mode = ArcChord;
    xd->wgc = XCreateGC(display, xd->window, GCArcMode, &gcv);
    XSetState(display, xd->wgc, blackpixel, whitepixel, GXcopy, AllPlanes);

    /* ensure that line drawing is set up at the first graphics call */
    xd->lty = -1;
    xd->lwd = -1;
    xd->lend = 0;
    xd->ljoin = 0;

    numX11Devices++;
    return TRUE;
}

/* Return a non-relocatable copy of a string */

static char *SaveFontSpec(SEXP sxp, int offset)
{
    char *s;
    if(!isString(sxp) || length(sxp) <= offset)
	error(_("invalid font specification"));
    s = R_alloc(strlen(CHAR(STRING_ELT(sxp, offset)))+1, sizeof(char));
    strcpy(s, CHAR(STRING_ELT(sxp, offset)));
    return s;
}

/*
 * Take the fontfamily from a gcontext (which is device-independent)
 * and convert it into an X11-specific font description using
 * the X11 font database (see src/library/graphics/R/unix/x11.R)
 *
 * IF gcontext fontfamily is empty ("")
 * OR IF can't find gcontext fontfamily in font database
 * THEN return xd->basefontfamily (the family set up when the
 *   device was created)
 */
static char* translateFontFamily(char* family, pX11Desc xd)
{
    SEXP graphicsNS, x11env, fontdb, fontnames;
    int i, nfonts;
    char* result = xd->basefontfamily;
    PROTECT_INDEX xpi;

    PROTECT(graphicsNS = R_FindNamespace(ScalarString(mkChar("grDevices"))));
    PROTECT_WITH_INDEX(x11env = findVar(install(".X11env"), graphicsNS), &xpi);
    if(TYPEOF(x11env) == PROMSXP)
	REPROTECT(x11env = eval(x11env, graphicsNS), xpi);
    PROTECT(fontdb = findVar(install(".X11.Fonts"), x11env));
    PROTECT(fontnames = getAttrib(fontdb, R_NamesSymbol));
    nfonts = LENGTH(fontdb);
    if (family[0]) {
	Rboolean found = FALSE;
	for (i = 0; i < nfonts && !found; i++) {
	    const char* fontFamily = CHAR(STRING_ELT(fontnames, i));
	    if (strcmp(family, fontFamily) == 0) {
		found = TRUE;
		result = SaveFontSpec(VECTOR_ELT(fontdb, i), 0);
	    }
	}
	if (!found)
	    warning(_("font family not found in X11 font database"));
    }
    UNPROTECT(4);
    return result;
}

static double X11_StrWidth(const char *str, const pGEcontext gc, pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    SetFont(gc, xd);

    if (xd->font->type == One_Font)
	return (double) XTextWidth(xd->font->font, str, (int)strlen(str));
    else  {
#ifdef HAVE_XUTF8TEXTESCAPEMENT
	if(utf8locale)
	    return (double) Xutf8TextEscapement(xd->font->fontset,
						str, (int)strlen(str));
	else
#endif
	    return (double) XmbTextEscapement(xd->font->fontset,
					      str, (int)strlen(str));
    }
}


	/* Character Metric Information */
	/* Passing c == 0 gets font information */

static void X11_MetricInfo(int c, const pGEcontext gc,
			   double* ascent, double* descent,
			   double* width, pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    int first = 0, last = 0;
    XFontStruct *f = NULL;

    if (c < 0)
	error(_("invalid use of %d < 0 in '%s'"), c, "X11_MetricInfo");

    SetFont(gc, xd);

    *ascent = 0; *descent = 0; *width = 0; /* fallback position */
    if (xd->font) {
	if (xd->font->type != One_Font) {
	    char **ml; XFontStruct **fs_list;
#ifdef DEBUG_X11
	    int i, cnt = XFontsOfFontSet(xd->font->fontset, &fs_list, &ml);

	    for (i = 0; i < cnt; i++) printf("%s\n", ml[i]);
	    printf("--- end of fontlist ---\n\n");
#else
	    XFontsOfFontSet(xd->font->fontset, &fs_list, &ml);
#endif

	    f = fs_list[0];
	} else f = xd->font->font;
	first = f->min_char_or_byte2;
	last = f->max_char_or_byte2;
    } else return;

    if (c == 0) {
	*ascent = f->ascent;
	*descent = f->descent;
	*width = f->max_bounds.width;
	return;
    }

    if (xd->font->type != One_Font) {  /* so an MBCS */
	XRectangle ink, log;
	char buf[16];

	ucstomb(buf, (unsigned int) c);
#ifdef HAVE_XUTF8TEXTEXTENTS
	if(utf8locale)
	    Xutf8TextExtents(xd->font->fontset, buf, (int)strlen(buf), &ink, &log);
	else
#endif
	    XmbTextExtents(xd->font->fontset, buf, (int)strlen(buf), &ink, &log);
	/* Rprintf("%d %d %d %d\n", ink.x, ink.y, ink.width, ink.height);
	   Rprintf("%d %d %d %d\n", log.x, log.y, log.width, log.height); */
	*ascent = -ink.y;
	*descent = ink.y + ink.height;
	/* <FIXME> why logical and not ink width? */
	*width = log.width;
	/* Rprintf("%d %lc w=%f a=%f d=%f\n", c, wc[0],
		    *width, *ascent, *descent);*/
    } else { /* symbol font */
	if(first <= c && c <= last) {
	  /*
	   * <MBCS-FIXED>: try demo(lm.glm,package="stats")
	   * per_char is NULL case.
	   */
	  if(f->per_char) {
	    *ascent = f->per_char[c-first].ascent;
	    *descent = f->per_char[c-first].descent;
	    *width = f->per_char[c-first].width;
	  } else {
	    *ascent = f->max_bounds.ascent;
	    *descent = f->max_bounds.descent;
	    *width = f->max_bounds.width;
	  }
	}
    }
}

static void X11_Clip(double x0, double x1, double y0, double y1,
			pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    if (x0 < x1) {
	xd->clip.x = (unsigned short) x0 ;
	xd->clip.width = (unsigned short) x1 - (unsigned short) x0 + 1;
    }
    else {
	xd->clip.x = (unsigned short) x1;
	xd->clip.width = (unsigned short) x0 - (unsigned short) x1 + 1;
    }

    if (y0 < y1) {
	xd->clip.y = (unsigned short) y0;
	xd->clip.height = (unsigned short) y1 -  (unsigned short) y0 + 1;
    }
    else {
	xd->clip.y = (unsigned short) y1;
	xd->clip.height = (unsigned short) y0 - (unsigned short) y1 + 1;
    }

    XSetClipRectangles(display, xd->wgc, 0, 0, &(xd->clip), 1, Unsorted);
}

static void X11_Size(double *left, double *right,
		     double *bottom, double *top,
		     pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    *left = 0.0;
    *right = xd->windowWidth;
    *bottom = xd->windowHeight;
    *top = 0.0;
}

static void X11_NewPage(const pGEcontext gc, pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    xd->warn_trans = FALSE;
    if (xd->type > WINDOW) {
	if (xd->npages++) {
	    /* try to preserve the page we do have */
	    if (xd->type != XIMAGE) X11_Close_bitmap(xd);
	    if (xd->type != XIMAGE && xd->fp != NULL) fclose(xd->fp);
	    if (xd->type == PNG || xd->type == JPEG || xd->type == BMP) {
		char buf[PATH_MAX];
		snprintf(buf, PATH_MAX, xd->filename, xd->npages);
		xd->fp = R_fopen(R_ExpandFileName(buf), "w");
		if (!xd->fp)
		    error(_("could not open file '%s'"), buf);
	    }
	}
	CheckAlpha(gc->fill, xd);
	xd->fill = R_OPAQUE(gc->fill) ? gc->fill: PNG_TRANS;
	SetColor(xd->fill, xd);
	xd->clip.x = 0; xd->clip.width = (unsigned short)xd->windowWidth;
	xd->clip.y = 0; xd->clip.height = (unsigned short)xd->windowHeight;
	XSetClipRectangles(display, xd->wgc, 0, 0, &(xd->clip), 1, Unsorted);
	XFillRectangle(display, xd->window, xd->wgc, 0, 0,
		       xd->windowWidth, xd->windowHeight);
	return;
    }

    FreeX11Colors();
    if ( (model == PSEUDOCOLOR2) || (xd->fill != gc->fill)) {
	xd->fill = R_OPAQUE(gc->fill) ? gc->fill : xd->canvas;
	whitepixel = GetX11Pixel(R_RED(xd->fill),R_GREEN(xd->fill),R_BLUE(xd->fill));
	XSetWindowBackground(display, xd->window, whitepixel);
    }
    XClearWindow(display, xd->window);
    XSync(display, 0);
}

#include "bitmap.h"

static int knowncols[512];

static unsigned int bitgp(void *xi, int x, int y)
{
    int i, r, g, b;
    XColor xcol;

    /*	returns the colour of the (x,y) pixel stored as RGB */
    i = (int) XGetPixel((XImage *) xi, y, x);
    switch(model) {
    case MONOCHROME:
	return i == 0 ? 0xFFFFFFFF : 0;
    case GRAYSCALE:
    case PSEUDOCOLOR1:
    case PSEUDOCOLOR2:
	if (i < 512) {
	    if (knowncols[i] < 0) {
		xcol.pixel = i;
		XQueryColor(display, colormap, &xcol);
		knowncols[i] = ((xcol.red>>8)<<16) | ((xcol.green>>8)<<8)
		    | (xcol.blue>>8);
	    }
	    return knowncols[i] | 0xFF000000;
	} else {
	    xcol.pixel = i;
	    XQueryColor(display, colormap, &xcol);
	    return ((xcol.red>>8)<<16) | ((xcol.green>>8)<<8) | (xcol.blue>>8);
	}
    case TRUECOLOR:
	r = ((i>>RShift)&RMask) * 255 /(RMask);
	g = ((i>>GShift)&GMask) * 255 /(GMask);
	b = ((i>>BShift)&BMask) * 255 /(BMask);
	return (r<<16) | (g<<8) | b | 0xFF000000;
    default:
	return 0;
    }
    /* return 0;  not reached, needed for some compilers */
}

static void X11_Close_bitmap(pX11Desc xd)
{
    int i;
    XImage *xi;
    for (i = 0; i < 512; i++) knowncols[i] = -1;
    xi = XGetImage(display, xd->window, 0, 0,
		   xd->windowWidth, xd->windowHeight,
		   AllPlanes, ZPixmap);
    if (xd->type == PNG) {
	unsigned int pngtrans = PNG_TRANS;
	if(model == TRUECOLOR) {
	    int i, r, g, b;
	    /* some 'truecolor' displays distort colours */
	    i = GetX11Pixel(R_RED(PNG_TRANS),
			    R_GREEN(PNG_TRANS),
			    R_BLUE(PNG_TRANS));
	    r = ((i>>RShift)&RMask) * 255 /(RMask);
	    g = ((i>>GShift)&GMask) * 255 /(GMask);
	    b = ((i>>BShift)&BMask) * 255 /(BMask);
	    pngtrans = (r<<16) | (g<<8) | b | 0xFF000000;
	}
	R_SaveAsPng(xi, xd->windowWidth, xd->windowHeight,
		    bitgp, 0, xd->fp,
		    (xd->fill != PNG_TRANS) ? 0 : pngtrans, xd->res_dpi);
    } else if (xd->type == JPEG)
	R_SaveAsJpeg(xi, xd->windowWidth, xd->windowHeight,
		     bitgp, 0, xd->quality, xd->fp, xd->res_dpi);
    else if (xd->type == BMP)
	R_SaveAsBmp(xi, xd->windowWidth, xd->windowHeight,
		    bitgp, 0, xd->fp, xd->res_dpi);
    else if (xd->type == TIFF) {
	char buf[PATH_MAX];
	snprintf(buf, PATH_MAX, xd->filename, xd->npages);
	R_SaveAsTIFF(xi, xd->windowWidth, xd->windowHeight,
		     bitgp, 0, R_ExpandFileName(buf), xd->res_dpi,
		     xd->quality);
    }

    XDestroyImage(xi);
}

static void X11_Close(pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    if (xd->type == WINDOW) {
#ifdef HAVE_WORKING_CAIRO
	if(xd->buffered > 1) removeBuffering(xd);
#endif
	/* process pending events */
	/* set block on destroy events */
	inclose = TRUE;
	R_ProcessX11Events((void*) NULL);

#ifdef HAVE_WORKING_CAIRO
	if(xd->useCairo) {
	    if(xd->cs) cairo_surface_destroy(xd->cs);
	    if(xd->cc) cairo_destroy(xd->cc);
	    if(xd->xcs) cairo_surface_destroy(xd->xcs);
	    if(xd->xcc) cairo_destroy(xd->xcc);
	}
#endif

	XFreeGC(display, xd->wgc);
	XDestroyWindow(display, xd->window);
	XSync(display, 0);
    } else {
	if (xd->npages && xd->type != XIMAGE) X11_Close_bitmap(xd);
	XFreeGC(display, xd->wgc);
	XFreePixmap(display, xd->window);
	if (xd->type != XIMAGE && xd->fp != NULL) fclose(xd->fp);
    }

    numX11Devices--;
    if (numX11Devices == 0)  {
	int fd = ConnectionNumber(display);
	/* Free Resources Here */
	while (nfonts--)
	      R_XFreeFont(display, fontcache[nfonts].font);
	nfonts = 0;
	if(xd->handleOwnEvents == FALSE)
	    removeInputHandler(&R_InputHandlers,
			       getInputHandler(R_InputHandlers,fd));
	if(arrow_cursor) XFreeCursor(display, arrow_cursor);
	if(cross_cursor) XFreeCursor(display, cross_cursor);
	if(watch_cursor) XFreeCursor(display, watch_cursor);
	arrow_cursor = cross_cursor = watch_cursor = (Cursor) 0;
	XCloseDisplay(display);
	displayOpen = FALSE;
    }

    free(xd);
    inclose = FALSE;
}

static void X11_Activate(pDevDesc dd)
{
    char t[150];
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    if (xd->type > WINDOW) return;
    if(xd->title[0]) {
	snprintf(t, 140, xd->title, ndevNumber(dd) + 1);
	t[139] = '\0';
    } else {
	sprintf(t, "R Graphics: Device %d", ndevNumber(dd) + 1);
    }
    strcat(t, " (ACTIVE)");
    XStoreName(display, xd->window, t);
    XSync(display, 0);
}

static void X11_Deactivate(pDevDesc dd)
{
    char t[150];
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    if (xd->type > WINDOW) return;
    if(xd->title[0]) {
	snprintf(t, 140, xd->title, ndevNumber(dd) + 1);
	t[139] = '\0';
    } else {
	sprintf(t, "R Graphics: Device %d", ndevNumber(dd) + 1);
    }
    strcat(t, " (inactive)");
    XStoreName(display, xd->window, t);
    XSync(display, 0);
}

static void X11_Rect(double x0, double y0, double x1, double y1,
		     const pGEcontext gc, pDevDesc dd)
{
    double tmp;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    if (x0 > x1) {
	tmp = x0;
	x0 = x1;
	x1 = tmp;
    }
    if (y0 > y1) {
	tmp = y0;
	y0 = y1;
	y1 = tmp;
    }
    CheckAlpha(gc->fill, xd);
    if (R_OPAQUE(gc->fill)) {
	SetColor(gc->fill, xd);
	XFillRectangle(display, xd->window, xd->wgc, (int)x0, (int)y0,
		       (int)x1 - (int)x0, (int)y1 - (int)y0);
    }
    CheckAlpha(gc->col, xd);
    if (R_OPAQUE(gc->col)) {
	SetColor(gc->col, xd);
	SetLinetype(gc, xd);
	XDrawRectangle(display, xd->window, xd->wgc, (int)x0, (int)y0,
		       (int)x1 - (int)x0, (int)y1 - (int)y0);
    }
}

static void X11_Path(double *x, double *y,
                     int npoly, int *nper,
                     Rboolean winding,
                     const pGEcontext gc, pDevDesc dd)
{
    warning(_("%s not available for this device"), "Path drawing");
}

static unsigned int makeX11Pixel(unsigned int * rasterImage, int pixel) {
    return GetX11Pixel(R_RED(rasterImage[pixel]), 
                       R_GREEN(rasterImage[pixel]), 
                       R_BLUE(rasterImage[pixel]));
}

static void flipRaster(unsigned int *rasterImage,
                       int imageWidth, int imageHeight,
                       int invertX, int invertY,
                       unsigned int *flippedRaster) {
    int i, j;
    int rowInc, rowOff, colInc, colOff;

    if (invertX) {
        colInc = -1;
        colOff = imageWidth - 1;
    } else {
        colInc = 1;
        colOff = 0;
    }
    if (invertY) {
        rowInc = -1;
        rowOff = imageHeight - 1;
    } else {
        rowInc = 1;
        rowOff = 0;
    }

    for (i = 0; i < imageHeight ;i++) {
        for (j = 0; j < imageWidth; j++) {
            int row = (rowInc*i + rowOff);
            int col = (colInc*j + colOff);
            flippedRaster[i*imageWidth + j] = 
                rasterImage[row*imageWidth + col];
        }
    }
}

static void X11_Raster(unsigned int *raster, int w, int h,
                      double x, double y, 
                      double width, double height,
                      double rot, 
                      Rboolean interpolate,
                      const pGEcontext gc, pDevDesc dd)
{
    int i, j, pixel;
    int imageWidth;
    int imageHeight;
    int invertX = 0;
    int invertY = 0;
    double angle = rot*M_PI/180;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    XImage *image;
    unsigned int *rasterImage;
    const void *vmax = vmaxget();
   
    if (height < 0) {
        imageHeight = (int) -(height - .5);
        /* convert (x, y) from bottom-left to top-left */
        y = y - imageHeight*cos(angle);
        if (angle != 0) {
            x = x - imageHeight*sin(angle);
        }
    } else {
        imageHeight = (int) (height + .5);
        invertY = 1;
    }

    if (width < 0) {
        imageWidth = (int) -(width - .5);
        x = x - imageWidth*cos(angle);
        if (angle != 0)
            y = y + imageWidth*sin(angle);
        invertX = 1;
    } else {
        imageWidth = (int) (width + .5);
    }

    rasterImage = (unsigned int *) R_alloc(imageWidth * imageHeight,
                                           sizeof(unsigned int));
    if (interpolate) {
        R_GE_rasterInterpolate(raster, w, h, 
                               rasterImage, imageWidth, imageHeight);
    } else {
        R_GE_rasterScale(raster, w, h, 
                         rasterImage, imageWidth, imageHeight);
    }
    
    if (invertX || invertY) {
        unsigned int *flippedRaster;

        flippedRaster = (unsigned int *) R_alloc(imageWidth * imageHeight,
                                                 sizeof(unsigned int));
        flipRaster(rasterImage, imageWidth, imageHeight, 
                   invertX, invertY, flippedRaster);
        rasterImage = flippedRaster;
    }

    if (rot != 0) {
        
        int newW, newH;
        double xoff, yoff;
        unsigned int *resizedRaster, *rotatedRaster;

        R_GE_rasterRotatedSize(imageWidth, imageHeight, angle, &newW, &newH);
        R_GE_rasterRotatedOffset(imageWidth, imageHeight, angle, 0,
                                 &xoff, &yoff);

        resizedRaster = (unsigned int *) R_alloc(newW * newH, 
                                             sizeof(unsigned int));
        R_GE_rasterResizeForRotation(rasterImage, imageWidth, imageHeight, 
                                     resizedRaster, newW, newH, gc);

        rotatedRaster = (unsigned int *) R_alloc(newW * newH, 
                                                 sizeof(unsigned int));
        R_GE_rasterRotate(resizedRaster, newW, newH, angle, rotatedRaster, gc,
                          FALSE);                          
            
        /* 
         * Adjust (x, y) for resized and rotated image
         */
        x = x - (newW - imageWidth)/2 - xoff;
        y = y - (newH - imageHeight)/2 + yoff;        

        rasterImage = rotatedRaster;
        imageWidth = newW;
        imageHeight = newH;
    }

    image = XCreateImage(display, visual, depth,
                         ZPixmap,
                         0, /* offset */
                         /* This is just provides (at least enough)
                          * allocated memory for the image data;  
                          * each pixel is set separately below
                          */
                         (char *) rasterImage,
                         imageWidth, imageHeight,
                         depth >= 24 ? 32 : 16, /* bitmap_pad */
                         0); /* bytes_per_line: 0 means auto-calculate*/

    if (image == NULL || XInitImage(image) == 0)
        error(_("Unable to create XImage"));

    for (i = 0; i < imageHeight ;i++) {
        for (j = 0; j < imageWidth; j++) {
            pixel = i*imageWidth + j;
            XPutPixel(image, j, i, makeX11Pixel(rasterImage, pixel));
        }
    }

    XPutImage(display, xd->window, xd->wgc, 
              image, 0, 0,
              (int) x, (int) y, imageWidth, imageHeight);

    /* XFree() rather than XDestroyImage() because the latter
     * tries to free the image 'data' as well
     */
    XFree(image);

    vmaxset(vmax);
}

static SEXP X11_Cap(pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    XImage *image = XGetImage(display, xd->window, 0, 0,
                              xd->windowWidth, xd->windowHeight, 
                              AllPlanes, ZPixmap);
    SEXP raster = R_NilValue;

    if (image) {
        int i, j;
        SEXP dim;
        int size = xd->windowWidth * xd->windowHeight;
        const void *vmax = vmaxget();
        unsigned int *rint;

        PROTECT(raster = allocVector(INTSXP, size));
        
        /* Copy each byte of screen to an R matrix. 
         * The ARGB32 needs to be converted to an R ABGR32 */
        rint = (unsigned int *) INTEGER(raster);
        for (i = 0; i < xd->windowHeight; i++) {
            for (j = 0; j < xd->windowWidth; j++) {
                /* 
                 * Convert each pixel in image to an R colour
                 */
                rint[i*xd->windowWidth + j] = bitgp((void *) image, i, j);
            }
        }
        PROTECT(dim = allocVector(INTSXP, 2));
        INTEGER(dim)[0] = xd->windowHeight;
        INTEGER(dim)[1] = xd->windowWidth;
        setAttrib(raster, R_DimSymbol, dim);
    
        UNPROTECT(2);

        XDestroyImage(image);
        vmaxset(vmax);
    }

    return raster;
}

static void X11_Circle(double x, double y, double r,
		       const pGEcontext gc, pDevDesc dd)
{
    int ir, ix, iy;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    ir = (int)floor(r + 0.5);

    ix = (int)x;
    iy = (int)y;
    CheckAlpha(gc->fill, xd);
    if (R_OPAQUE(gc->fill)) {
	SetColor(gc->fill, xd);
	XFillArc(display, xd->window, xd->wgc,
		 ix-ir, iy-ir, 2*ir, 2*ir, 0, 23040);
    }
    CheckAlpha(gc->col, xd);
    if (R_OPAQUE(gc->col)) {
	SetLinetype(gc, xd);
	SetColor(gc->col, xd);
	XDrawArc(display, xd->window, xd->wgc,
		 ix-ir, iy-ir, 2*ir, 2*ir, 0, 23040);
    }
}

static void X11_Line(double x1, double y1, double x2, double y2,
		     const pGEcontext gc, pDevDesc dd)
{
    int xx1, yy1, xx2, yy2;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    /* In-place conversion ok */

    xx1 = (int) x1;
    yy1 = (int) y1;
    xx2 = (int) x2;
    yy2 = (int) y2;

    CheckAlpha(gc->col, xd);
    if (R_OPAQUE(gc->col)) {
	SetColor(gc->col, xd);
	SetLinetype(gc, xd);
	XDrawLine(display, xd->window, xd->wgc, xx1, yy1, xx2, yy2);
    }
}

static void X11_Polyline(int n, double *x, double *y,
			 const pGEcontext gc, pDevDesc dd)
{
    const void *vmax = vmaxget();
    XPoint *points;
    int i, j;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    points = (XPoint *) R_alloc(n, sizeof(XPoint));

    for(i = 0 ; i < n ; i++) {
	points[i].x = (short)(x[i]);
	points[i].y = (short)(y[i]);
    }

    CheckAlpha(gc->col, xd);
    if (R_OPAQUE(gc->col)) {
	SetColor(gc->col, xd);
	SetLinetype(gc, xd);
/* Some X servers need npoints < 64K */
	for(i = 0; i < n; i+= 10000-1) {
	    j = n - i;
	    j = (j <= 10000) ? j: 10000; /* allow for overlap */
	    XDrawLines(display, xd->window, xd->wgc, points+i, j,
		       CoordModeOrigin);
	}
    }

    vmaxset(vmax);
}

static void X11_Polygon(int n, double *x, double *y,
			const pGEcontext gc, pDevDesc dd)
{
    const void *vmax = vmaxget();
    XPoint *points;
    int i;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    points = (XPoint *) R_alloc(n+1, sizeof(XPoint));

    for (i = 0 ; i < n ; i++) {
	points[i].x = (short)(x[i]);
	points[i].y = (short)(y[i]);
    }
    points[n].x = (short)(x[0]);
    points[n].y = (short)(y[0]);
    CheckAlpha(gc->fill, xd);
    if (R_OPAQUE(gc->fill)) {
	SetColor(gc->fill, xd);
	XFillPolygon(display, xd->window, xd->wgc, points, n,
		     Complex, CoordModeOrigin);
    }
    CheckAlpha(gc->col, xd);
    if (R_OPAQUE(gc->col)) {
	SetColor(gc->col, xd);
	SetLinetype(gc, xd);
	XDrawLines(display, xd->window, xd->wgc, points, n+1, CoordModeOrigin);
    }

    vmaxset(vmax);
}


static void X11_Text(double x, double y,
		     const char *str, double rot, double hadj,
		     const pGEcontext gc, pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;

    SetFont(gc, xd);
    CheckAlpha(gc->col, xd);
    if (R_OPAQUE(gc->col)) {
	SetColor(gc->col, xd);
	XRfRotDrawString(display, xd->font, rot, xd->window,
			 xd->wgc, (int)x, (int)y, str);
    }
}

static Rboolean X11_Locator(double *x, double *y, pDevDesc dd)
{
    XEvent event;
    pDevDesc ddEvent;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    caddr_t temp;
    int done = 0;

    if (xd->type > WINDOW) return 0;
#ifdef HAVE_WORKING_CAIRO
    if (xd->holdlevel > 0)
	error(_("attempt to use the locator after dev.hold()"));
    if (xd->buffered) Cairo_update(xd);
#endif
    R_ProcessX11Events((void*)NULL);	/* discard pending events */
    if(xd->type==WINDOW) XDefineCursor(display, xd->window, cross_cursor);
    XSync(display, 1);
    /* handle X events as normal until get a button */
    /* click in the desired device */
    while (!done && displayOpen) {
	XNextEvent(display, &event);
	/* possibly later R_CheckUserInterrupt(); */
	if (event.type == ButtonPress) {
	    XFindContext(display, event.xbutton.window,
			 devPtrContext, &temp);
	    ddEvent = (pDevDesc) temp;
	    if (ddEvent == dd) {
		if (event.xbutton.button == Button1) {
		    int useBeep = asLogical(GetOption1(install("locatorBell")));
		    *x = event.xbutton.x;
		    *y = event.xbutton.y;
		       /* Make a beep! Was print "\07", but that
			  messes up some terminals. */
		    if(useBeep) XBell(display, X_BELL_VOLUME);
		    XSync(display, 0);
		    done = 1;
		}
		else
		    done = 2;
	    }
	}
	else
	    handleEvent(event);
    }
    /* In case it got closed asynchronously, PR#14872 */
    if (!displayOpen) return 0;
    /* if it was a Button1 succeed, otherwise fail */
    if(xd->type==WINDOW) XDefineCursor(display, xd->window, arrow_cursor);
    XSync(display, 0);
    return (done == 1);
}

static int translate_key(KeySym keysym)
{
    if ((keysym >= XK_F1) && (keysym <= XK_F12))
    	return knF1 + (int)keysym - XK_F1;
    else {
    	switch(keysym) {
	case XK_Left: return knLEFT;
	case XK_Up:   return knUP;
	case XK_Right:return knRIGHT;
	case XK_Down: return knDOWN;
	case XK_Page_Up: 	return knPGUP;
	case XK_Page_Down: 	return knPGDN;
	case XK_End:  return knEND;
	case XK_Begin:return knHOME;
	case XK_Insert:  	return knINS;
	}
    }
    return knUNKNOWN;
}

static void X11_eventHelper(pDevDesc dd, int code)
{
    XEvent event;
    pDevDesc ddEvent;
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    caddr_t temp;
    int done = 0;

    if (xd->type > WINDOW) return;
    if (code == 1) {
    	R_ProcessX11Events((void*)NULL);	/* discard pending events */
    	if (isEnvironment(dd->eventEnv)) {
    	    SEXP prompt = findVar(install("prompt"), dd->eventEnv);
    	    if (isString(prompt) && length(prompt) == 1) {
    		 PROTECT(prompt);
    		 XStoreName(display, xd->window, CHAR(asChar(prompt)));
    		 UNPROTECT(1);
    	    } else 
    	    	XStoreName(display, xd->window, "");
    	}
    	XSync(display, 1);
    } else if (code == 2) {
	if (doesIdle(dd) && (XPending(display) == 0)) {
            // The device descriptor event environment has an idle
            // handler, and there are no pending events
            doIdle(dd);
            return;
        }
        XNextEvent(display, &event);
	if (event.type == ButtonRelease || event.type == ButtonPress || event.type == MotionNotify) {
	    int RButtons;
	    XFindContext(display, event.xbutton.window,
			 devPtrContext, &temp);
	    ddEvent = (pDevDesc) temp;
	    if (ddEvent == dd && dd->gettingEvent) {
		if (event.type == MotionNotify) { /* Because of PointerMotionHintMask, need to update */
		    Window root, child;
		    int rootX, rootY, winX, winY;
		    unsigned int mask;
		    if (!XQueryPointer(display, event.xbutton.window,
                                      &root, &child, &rootX, &rootY,
				      &winX, &winY, &mask)) {
			done = 1;
		    } else {
			event.xbutton.x = winX;
			event.xbutton.y = winY;
		    }
		    RButtons = mask >> 8;  /* See PR#16700 */
		} else
		    RButtons = 1 << (event.xbutton.button - 1);
		if (!done) {
        	    doMouseEvent(dd, event.type == ButtonRelease ? meMouseUp :
        	                 event.type == ButtonPress ? meMouseDown : meMouseMove, 
        	                 RButtons, event.xbutton.x, event.xbutton.y);
                    XSync(display, 0);
                    done = 1;
		}
    	    }
	} else if (event.type == KeyPress) {
	    char keybuffer[13] = "";
	    char *keystart=keybuffer;
	    XComposeStatus compose;
  	    KeySym keysym;
	    int keycode;
	    if (event.xkey.state & ControlMask) {
	    	keystart += 5; 
	    	sprintf(keybuffer, "ctrl-"); /* report control keys using labels like "ctrl-A" */
	    	event.xkey.state &= ~ControlMask;
	    	event.xkey.state |= ShiftMask;
	    }
      	    XLookupString(&event.xkey, keystart, 
			  sizeof(keybuffer)-(int)(keystart-keybuffer), 
			  &keysym, &compose);
      	    /* Rprintf("keysym=%x\n", keysym); */
      	    if ((keycode = translate_key(keysym)) > knUNKNOWN)
      	    	doKeybd(dd, keycode, NULL);
      	    else if (*keystart)
	    	doKeybd(dd, knUNKNOWN, keybuffer);
	    done = 1;
	}
	if (!done) 
	    handleEvent(event);
    } else if (code == 0) {
	/* Restore the default title */
	if (ndevNumber(dd) == curDevice())
	    X11_Activate(dd);
	else
	    X11_Deactivate(dd);  
    }

    return;
}

	/********************************************************/
	/* device_Mode is called whenever the graphics engine	*/
	/* starts drawing (mode=1) or stops drawing (mode=0)	*/
	/* the device is not required to do anything		*/
	/********************************************************/

static void X11_Mode(int mode, pDevDesc dd)
{
    pX11Desc xd = (pX11Desc) dd->deviceSpecific;
    if(xd->holdlevel > 0) {
#ifdef HAVE_WORKING_CAIRO
	if(mode == 0 && xd->buffered > 1)
	    xd->last_activity = currentTime();
#endif
	return;
    }
    if(mode == 1) {
	if(xd->type==WINDOW) XDefineCursor(display, xd->window, watch_cursor);
	XSync(display, 0);
    }
    if(mode == 0) {
#ifdef HAVE_WORKING_CAIRO
	if(xd->buffered > 1) {
	    xd->last_activity = currentTime();
	    if((currentTime() - xd->last) > 0.5 /* 5*xd->update_interval */)
		Cairo_update(xd);
	    return;
	}
	if(xd->buffered) {
	    cairo_paint(xd->xcc);
	    cairo_surface_flush(xd->xcs);
	}
	
#endif
	if(xd->type==WINDOW) XDefineCursor(display, xd->window, arrow_cursor);
	XSync(display, 0);
    }
}


	/*  X11 Device Driver Arguments	:	*/
	/*	1) display name			*/
	/*	2) width (inches)		*/
	/*	3) height (inches)		*/
	/*	4) base pointsize		*/
	/*	5) gamma correction factor	*/
	/*	6) colormodel,			*/
	/*	 see X_COLORTYPE at top of file */
	/*	7) maxcube			*/

Rboolean X11DeviceDriver(pDevDesc dd,
			 const char *disp_name,
			 double width,
			 double height,
			 double pointsize,
			 double gamma_fac,
			 X_COLORTYPE colormodel,
			 int maxcube,
			 int bgcolor,
			 int canvascolor,
			 SEXP sfonts,
			 int res,
			 int xpos, int ypos,
			 const char *title,
			 int useCairo,
			 int antialias,
			 const char *family)
{
    pX11Desc xd;
    const char *fn;

    xd = Rf_allocX11DeviceDesc(pointsize);
    if(!xd) return FALSE;
    xd->bg = bgcolor;
#ifdef HAVE_WORKING_CAIRO
    xd->useCairo = useCairo != 0;
    xd->buffered = 0;
    switch(useCairo) {
    case 0: break; /* Xlib */
    case 1: xd->buffered = 1; break; /* cairo */
    case 2: xd->buffered = 0; break; /* nbcairo */
    case 3: xd->buffered = 2; break; /* dbcairo */
    default:
	warning("that type is not supported on this platform - using \"nbcairo\"");
	xd->buffered = 0;
    }
    if(useCairo) {
	switch(antialias){
	case 1: xd->antialias = CAIRO_ANTIALIAS_DEFAULT; break;
	case 2: xd->antialias = CAIRO_ANTIALIAS_NONE; break;
	case 3: xd->antialias = CAIRO_ANTIALIAS_GRAY; break;
	case 4: xd->antialias = CAIRO_ANTIALIAS_SUBPIXEL; break;
	}
    }
#else
    /* Currently this gets caught at R level */
    if(useCairo) {
	warning("cairo-based types are not supported on this build - using \"Xlib\"");
	useCairo = FALSE;
    }
#endif

    if(!useCairo) {
	if(strlen(fn = CHAR(STRING_ELT(sfonts, 0))) > 499) {
	    strcpy(xd->basefontfamily, fontname);
	    strcpy(xd->fontfamily, fontname);
	} else {
	    strcpy(xd->basefontfamily, fn);
	    strcpy(xd->fontfamily, fn);
	}
	if(strlen(fn = CHAR(STRING_ELT(sfonts, 1))) > 499)
	    strcpy(xd->symbolfamily, symbolname);
	else strcpy(xd->symbolfamily, fn);
    } else strcpy(xd->basefontfamily, family);

    /*	Start the Device Driver and Hardcopy.  */

    strncpy(xd->title, title, 100);
    xd->title[100] = '\0';

#ifdef HAVE_WORKING_CAIRO
    {
	SEXP timeouts = GetOption1(install("X11updates"));
	double tm = asReal(timeouts);
	xd->update_interval = (ISNAN(tm) || tm < 0) ? 0.10 : tm;
    }
#endif

    if (!X11_Open(dd, xd, disp_name, width, height,
		  gamma_fac, colormodel, maxcube, bgcolor,
		  canvascolor, res, xpos, ypos)) {
	free(xd);
	return FALSE;
    }

    Rf_setX11DeviceData(dd, gamma_fac, xd);
    xd->fill = 0xffffffff; /* this is needed to ensure that the
			      first newpage does set whitecolor
			      if par("bg") is not transparent */

#if BUG
    R_ProcessX11Events((void*) NULL);
#endif

    return TRUE;
}

/**
  This fills the general device structure (dd) with the X-specific
  methods/functions. It also specifies the current values of the
  dimensions of the device, and establishes the fonts, line styles, etc.
 */
int
Rf_setX11DeviceData(pDevDesc dd, double gamma_fac, pX11Desc xd)
{
    double ps = xd->pointsize;
    int res0 = (xd->res_dpi > 0) ? xd->res_dpi : 72;
    /*	Set up Data Structures. */

#ifdef HAVE_WORKING_CAIRO
    if(xd->useCairo) {
	dd->newPage = Cairo_NewPage;
	dd->clip = Cairo_Clip;
	dd->rect = Cairo_Rect;
	dd->circle = Cairo_Circle;
	dd->line = Cairo_Line;
	dd->polyline = Cairo_Polyline;
	dd->polygon = Cairo_Polygon;
        dd->path = Cairo_Path;
        dd->raster = Cairo_Raster;
        dd->cap = Cairo_Cap;
	dd->hasTextUTF8 = TRUE;
	dd->wantSymbolUTF8 = TRUE;
#ifdef HAVE_PANGOCAIRO
	dd->metricInfo = PangoCairo_MetricInfo;
	dd->strWidth = dd->strWidthUTF8 = PangoCairo_StrWidth;
	dd->text = dd->textUTF8 = PangoCairo_Text;
#else
	dd->metricInfo = Cairo_MetricInfo;
	dd->strWidth = dd->strWidthUTF8 = Cairo_StrWidth;
	dd->text = dd->textUTF8 = Cairo_Text;
#endif
	dd->holdflush = Cairo_holdflush;
	dd->haveTransparency = 2;
	dd->haveTransparentBg = 3;
	dd->haveRaster = 2;
	dd->haveCapture = (xd->type > WINDOW) ? 1 : 2;
	dd->haveLocator = (xd->type > WINDOW) ? 1 : 2;
    } else
#endif
    {
	dd->newPage = X11_NewPage;
	dd->clip = X11_Clip;
	dd->strWidth = X11_StrWidth;
	dd->text = X11_Text;
	dd->rect = X11_Rect;
        dd->path = X11_Path;
        dd->raster     = X11_Raster;
        dd->cap        = X11_Cap;
	dd->circle = X11_Circle;
	dd->line = X11_Line;
	dd->polyline = X11_Polyline;
	dd->polygon = X11_Polygon;
	dd->metricInfo = X11_MetricInfo;
	dd->hasTextUTF8 = FALSE;

	dd->haveTransparency = 1;
	dd->haveTransparentBg = 2;
	dd->haveRaster = 3;
	dd->haveCapture = (xd->type > WINDOW) ? 1 : 2;
	dd->haveLocator = (xd->type > WINDOW) ? 1 : 2;
    }

    dd->eventHelper = X11_eventHelper;
    dd->canGenMouseDown = TRUE;
    dd->canGenMouseUp = TRUE;
    dd->canGenMouseMove = TRUE;
    dd->canGenKeybd = TRUE;
    dd->canGenIdle = TRUE;

    dd->activate = X11_Activate;
    dd->close = X11_Close;
    dd->deactivate = X11_Deactivate;
    dd->size = X11_Size;
    dd->locator = X11_Locator;
    dd->mode = X11_Mode;
    dd->useRotatedTextInContour = FALSE;

    /* Set required graphics parameters. */

    /* Window Dimensions in Pixels */
    /* Initialise the clipping rect too */

    dd->left = dd->clipLeft = 0;			/* left */
    dd->right = dd->clipRight = xd->windowWidth;	/* right */
    dd->bottom = dd->clipBottom = xd->windowHeight;	/* bottom */
    dd->top = dd->clipTop = 0;			/* top */

    /* Nominal Character Sizes in Pixels */
    /* Recommendation from 'R internals': changed for 2.7.0 */
    /* Inches per raster unit */

    /* ps is in points, we want this in device units */
    if(xd->type == PNG || xd->type == JPEG ||
       xd->type == BMP || xd->type == TIFF) {
	dd->cra[0] = 0.9*ps * res0/72.0;
	dd->cra[1] = 1.2*ps * res0/72.0;
	dd->ipr[0] =  dd->ipr[1] = 1.0/res0;
	xd->lwdscale = res0/96.0;
    } else if(xd->type >= SVG) { /* SVG, PDF, PS -- unused */
	/* Device units are bp */
	dd->cra[0] = 0.9*ps;
	dd->cra[1] = 1.2*ps;
	dd->ipr[0] =  dd->ipr[1] = 1.0/72.0;
	xd->lwdscale = 1.0/96.0;
    } else {
	dd->cra[0] = 0.9*ps * 1.0/(72.0*pixelWidth());
	dd->cra[1] = 1.2*ps * 1.0/(72.0*pixelHeight());
	dd->ipr[0] = pixelWidth();
	dd->ipr[1] = pixelHeight();
	xd->lwdscale = 1.0/(96.0*pixelWidth());
#ifdef HAVE_WORKING_CAIRO
	if(xd->useCairo) {
# ifdef HAVE_PANGOCAIRO
	    /* Pango's default resolution is 96 dpi */
	    ps *= 1.0/(96.0*pixelWidth());
# else
	    /* Cairo's default resolution is 72 dpi */
	    ps *= 1.0/(72.0*pixelWidth());
# endif
	}
#endif
    }

    /* Character Addressing Offsets */
    /* These are used to plot a single plotting character */
    /* so that it is exactly over the plotting point */

    dd->xCharOffset = 0.4900;
    dd->yCharOffset = 0.3333;
    dd->yLineBias = 0.2;


    /* Device capabilities */

    dd->canClip = TRUE;
#ifdef HAVE_WORKING_CAIRO
    dd->canHAdj = xd->useCairo ? 2 : 0;
#else
    dd->canHAdj = 0;
#endif
    dd->canChangeGamma = FALSE;

    dd->startps = ps;
    xd->fontscale = 1.0;
    dd->startcol = xd->col;
    dd->startfill = xd->fill;
    dd->startlty = LTY_SOLID;
    dd->startfont = 1;
    dd->startgamma = gamma_fac;

    /* initialise x11 device description */
    /* (most of the work has been done in X11_Open) */
    xd->resize = 0;

    dd->deviceSpecific = (void *) xd;

    dd->displayListOn = TRUE;

    return TRUE;
}


/**
 This allocates an X11Desc instance  and sets its default values.
 */
pX11Desc Rf_allocX11DeviceDesc(double ps)
{
    pX11Desc xd;
    /* allocate new device description */
    if (!(xd = (pX11Desc)calloc(1, sizeof(X11Desc))))
	return NULL;

    /* From here on, if we need to bail out with "error", */
    /* then we must also free(xd). */

    /*	Font will load at first use.  */

    if (ps < 6 || ps > 24) ps = 12;
    xd->fontface = -1;
    xd->fontsize = -1;
    xd->pointsize = ps;
    xd->handleOwnEvents = FALSE;
    xd->window = (Window) NULL;

    return xd;
}


static
Rboolean in_R_GetX11Image(int d, void *pximage, int *pwidth, int *pheight)
{
    SEXP dev = elt(findVar(install(".Devices"), R_BaseEnv), d);

    if (TYPEOF(dev) != STRSXP ||
	!(strcmp(CHAR(STRING_ELT(dev, 0)), "XImage") == 0 ||
	  strncmp(CHAR(STRING_ELT(dev, 0)), "PNG", 3) == 0 ||
	  strncmp(CHAR(STRING_ELT(dev, 0)), "X11", 3) == 0))
	return FALSE;
    else {
	pX11Desc xd = GEgetDevice(d)->dev->deviceSpecific;

	*((XImage**) pximage) =
	    XGetImage(display, xd->window, 0, 0,
		      xd->windowWidth, xd->windowHeight,
		      AllPlanes, ZPixmap);
	*pwidth = xd->windowWidth;
	*pheight = xd->windowHeight;
	return TRUE;
    }
}

/**
   Allows callers to retrieve the current Display setting for the process.
 */
Display*
Rf_getX11Display(void)
{
    return(display);
}


/**
 Allows the caller to register the X11 Display object for the process.
 Typically this will be done when the first X device is created, but this allows
 other code to generate the Display object and then register it with the R graphics
 engine.
 In addition to providing the Display, the caller should also give the default value for the
 gamma factor and also the colormodel and color cube size. See the documentation for the x11()
 function.
 Finally, setHandlers controls whether the code establishes handlers for the X errors.
 */
int
Rf_setX11Display(Display *dpy, double gamma_fac, X_COLORTYPE colormodel,
		 int maxcube, Rboolean setHandlers)
{
/*    static int alreadyDone = 0;
    if(alreadyDone) return(TRUE);
    alreadyDone = 1; */
    display = dpy;

/* Note: this sets a global gamma, not just for the current device */
#define SETGAMMA
#ifdef SETGAMMA
    RedGamma   = gamma_fac;
    GreenGamma = gamma_fac;
    BlueGamma  = gamma_fac;
#endif
    screen = DefaultScreen(display);
    rootwin = DefaultRootWindow(display);
    depth = DefaultDepth(display, screen);
    visual = DefaultVisual(display, screen);
    colormap = DefaultColormap(display, screen);
    Vclass = visual->class;
    model = colormodel;
    maxcubesize = maxcube;
    SetupX11Color();
    devPtrContext = XUniqueContext();
    displayOpen = TRUE;
    /* set error handlers */
    if(setHandlers == TRUE) {
	XSetErrorHandler(R_X11Err);
	XSetIOErrorHandler(R_X11IOErr);
    }

    return(TRUE);
}

typedef Rboolean (*X11DeviceDriverRoutine)(pDevDesc, char*,
					   double, double, double, double,
					   X_COLORTYPE, int, int);

static void
Rf_addX11Device(const char *display, double width, double height, double ps,
		double gamma, int colormodel, int maxcubesize,
		int bgcolor, int canvascolor, const char *devname, SEXP sfonts,
		int res, int xpos, int ypos, const char *title,
		int useCairo, int antialias, const char * family, SEXP call)
{
    pDevDesc dev = NULL;
    pGEDevDesc dd;

    R_GE_checkVersionOrDie(R_GE_version);
    R_CheckDeviceAvailable();
    BEGIN_SUSPEND_INTERRUPTS {
	/* Allocate and initialize the device driver data */
	if (!(dev = (pDevDesc) calloc(1, sizeof(DevDesc)))) return;
	if (!X11DeviceDriver(dev, display, width, height,
			     ps, gamma, colormodel, maxcubesize,
			     bgcolor, canvascolor, sfonts, res,
			     xpos, ypos, title, useCairo, antialias, family)) {
	    free(dev);
	    errorcall(call, _("unable to start device %s"), devname);
	}
	dd = GEcreateDevDesc(dev);
	GEaddDevice2(dd, devname);
    } END_SUSPEND_INTERRUPTS;
}

static SEXP in_do_X11(SEXP call, SEXP op, SEXP args, SEXP env)
{
    const char *display, *cname, *devname, *title, *family;
    const void *vmax;
    double height, width, ps, gamma;
    int colormodel, maxcubesize, bgcolor, canvascolor, res, xpos, ypos,
	useCairo, antialias;
    SEXP sc, sfonts;

    checkArity(op, args);
    vmax = vmaxget();

    if(R_isForkedChild)
	error("a forked child should not open a graphics device");

    /* Decode the arguments */
    display = CHAR(STRING_ELT(CAR(args), 0)); args = CDR(args);
    width = asReal(CAR(args));	args = CDR(args);
    height = asReal(CAR(args)); args = CDR(args);
    if (width <= 0 || height <= 0)
	errorcall(call, _("invalid 'width' or 'height'"));
    ps = asReal(CAR(args)); args = CDR(args);
    gamma = asReal(CAR(args)); args = CDR(args);
    if (gamma < 0 || gamma > 100)
	errorcall(call, _("invalid '%s' value"), "gamma");

    if (!isValidString(CAR(args)))
	error(_("invalid colortype passed to X11 driver"));
    cname = CHAR(STRING_ELT(CAR(args), 0));
    if (strcmp(cname, "mono") == 0)
	colormodel = 0;
    else if (strcmp(cname, "gray") == 0 || strcmp(cname, "grey") == 0)
	colormodel = 1;
    else if (strcmp(cname, "pseudo.cube") == 0)
	colormodel = 2;
    else if (strcmp(cname, "pseudo") == 0)
	colormodel = 3;
    else if (strcmp(cname, "true") == 0)
	colormodel = 4;
    else {
	warningcall(call,
		    _("unknown X11 color/colour model -- using monochrome"));
	colormodel = 0;
    }
    args = CDR(args);
    maxcubesize = asInteger(CAR(args));
    if (maxcubesize < 1 || maxcubesize > 256)
	maxcubesize = 256;
    args = CDR(args);
    sc = CAR(args);
    if (!isString(sc) && !isInteger(sc) && !isLogical(sc) && !isReal(sc))
	errorcall(call, _("invalid '%s' value"), "bg");
    bgcolor = RGBpar(sc, 0);
    args = CDR(args);
    sc = CAR(args);
    if (!isString(sc) && !isInteger(sc) && !isLogical(sc) && !isReal(sc))
	errorcall(call, _("invalid '%s' value"), "canvas");
    canvascolor = RGBpar(sc, 0);
    args = CDR(args);
    sfonts = CAR(args);
    if (!isString(sfonts) || LENGTH(sfonts) != 2)
	errorcall(call, _("invalid '%s' value"), "fonts");
    args = CDR(args);
    res = asInteger(CAR(args));
    args = CDR(args);
    xpos = asInteger(CAR(args));
    args = CDR(args);
    ypos = asInteger(CAR(args));
    args = CDR(args);
    sc = CAR(args);
    if (!isString(sc) || LENGTH(sc) != 1)
	errorcall(call, _("invalid '%s' value"), "title");
    title = CHAR(STRING_ELT(sc, 0));
    args = CDR(args);
    useCairo = asInteger(CAR(args));
    if (useCairo == NA_INTEGER)
	errorcall(call, _("invalid '%s' value"), "type");
    args = CDR(args);
    antialias = asInteger(CAR(args));
    if (antialias == NA_INTEGER)
	errorcall(call, _("invalid '%s' value"), "antialias");
    args = CDR(args);
    sc = CAR(args);
    if (!isString(sc) || LENGTH(sc) != 1)
	errorcall(call, _("invalid '%s' value"), "family");
    family = CHAR(STRING_ELT(sc, 0));


    if (!strncmp(display, "png::", 5)) devname = "PNG";
    else if (!strncmp(display, "jpeg::", 6)) devname = "JPEG";
    else if (!strncmp(display, "tiff::", 6)) devname = "TIFF";
    else if (!strncmp(display, "bmp::", 5)) devname = "BMP";
    else if (!strcmp(display, "XImage")) devname = "XImage";
    else if (useCairo) devname = "X11cairo";
    else devname = "X11";

    Rf_addX11Device(display, width, height, ps, gamma, colormodel,
		    maxcubesize, bgcolor, canvascolor, devname, sfonts,
		    res, xpos, ypos, title, useCairo, antialias, family, call);
    vmaxset(vmax);
    return R_NilValue;
}


#ifdef HAVE_WORKING_CAIRO
static int stride;
static unsigned int Sbitgp(void *xi, int x, int y)
{
    unsigned int *data = xi;
    return data[x*stride+y] | 0xFF000000; /* force opaque */
}


/* savePlot(filename, type, device) */
static SEXP in_do_saveplot(SEXP call, SEXP op, SEXP args, SEXP env)
{
    int devNr;
    const char *fn, *type;
    pGEDevDesc gdd;
    pX11Desc xd;

    checkArity(op, args);
    if (!isString(CAR(args)) || LENGTH(CAR(args)) < 1)
	error(_("invalid '%s' argument"), "filename");
    fn = R_ExpandFileName(translateChar(STRING_ELT(CAR(args), 0)));
    if (!isString(CADR(args)) || LENGTH(CADR(args)) < 1)
	error(_("invalid '%s' argument"), "type");
    type = CHAR(STRING_ELT(CADR(args), 0));
    devNr = asInteger(CADDR(args));
    if (devNr == NA_INTEGER) error(_("invalid '%s' argument"), "device");
    gdd = GEgetDevice(devNr - 1); /* 0-based */
    if (!gdd->dirty) error(_("no plot on device to save"));
    xd = gdd->dev->deviceSpecific;
    if (!xd->cs || !xd->useCairo) error(_("not an open X11cairo device"));
    if (streql(type, "png")) {
	cairo_status_t res = cairo_surface_write_to_png(xd->cs, fn);
	if (res != CAIRO_STATUS_SUCCESS)
	    error("cairo error '%s'", cairo_status_to_string(res));
    }
    else if (streql(type, "jpeg")) {
	void *xi = cairo_image_surface_get_data(xd->cs);
	FILE *fp = R_fopen(fn, "w");
	if (!fp) error(_("cannot open file '%s'"), fn);
	stride = xd->windowWidth;
	R_SaveAsJpeg(xi, xd->windowWidth, xd->windowHeight,
		     Sbitgp, 0, 75, fp, 0);
	fclose(fp);
    } else if (streql(type, "tiff")) {
	void *xi = cairo_image_surface_get_data(xd->cs);
	stride = xd->windowWidth;
	R_SaveAsTIFF(xi, xd->windowWidth, xd->windowHeight,
		     Sbitgp, 0, fn, 0, 1L);
    } else
	error(_("invalid '%s' argument"), "type");
    return R_NilValue;
}
#else
static SEXP in_do_saveplot(SEXP call, SEXP op, SEXP args, SEXP env)
{
    error(_("savePlot() is not supported on this build"));
    return R_NilValue;
}
#endif


static int in_R_X11_access(void)
{
    char *p;
    X11IOhandler old;

    if (displayOpen) return TRUE;
    if(!(p = getenv("DISPLAY"))) return FALSE;
    /* Bill Dunlap sees an error when tunneling to a non-existent
       X11 connection that BDR cannot reproduce.  We leave a handler set
       if we get an error, but that is rare.
    */
    old = XSetIOErrorHandler(R_X11IOErrSimple);
    if ((display = XOpenDisplay(NULL)) == NULL) {
	XSetIOErrorHandler(old);
	return FALSE;
    } else {
	XCloseDisplay(display);
	XSetIOErrorHandler(old);
	return TRUE;
    }
}

static Rboolean in_R_X11readclp(Rclpconn this, char *type)
{
    Window clpwin;
    Atom sel = XA_PRIMARY, pty, pty_type;
    XEvent evt;
    unsigned char *buffer;
    unsigned long pty_size, pty_items;
    int pty_format, ret;
    Rboolean res = TRUE;

    if (!displayOpen) {
	if ((display = XOpenDisplay(NULL)) == NULL) {
	    warning(_("unable to contact X11 display"));
	    return FALSE;
	}
    }
    if(strcmp(type, "X11_secondary") == 0) sel = XA_SECONDARY;
    if(strcmp(type, "X11_clipboard") == 0)
#ifdef HAVE_X11_Xmu
      sel = XA_CLIPBOARD(display);
#else
      error("X11 clipboard selection is not supported on this system");
#endif

    pty = XInternAtom(display, "RCLIP_READ", False);

    clpwin = XCreateSimpleWindow(display, DefaultRootWindow(display),
				 0, 0, 1, 1, 0, 0, 0);
    /* <FIXME> this is not optimal in a UTF-8 locale.
       What we should do is see if UTF-8 extensions are available
       (via X_HAVE_UTF8_STRING) then ask with target TARGETS and see if
       UTF8_STRING is available.  See
       http://www.pps.jussieu.fr/~jch/software/UTF8_STRING/UTF8_STRING.text
    */

    /* send a selection request */
    ret = XConvertSelection(display, sel, XA_STRING, pty, clpwin, CurrentTime);

    /* wait for the response */
    while(1) {
	XNextEvent(display, &evt);
	if (evt.type == SelectionNotify) break;
    }

    /* find the size and format of the data in the selection */
    ret = XGetWindowProperty(display, clpwin, pty, 0, 0, False, AnyPropertyType,
			     &pty_type, &pty_format, &pty_items, &pty_size,
			     &buffer);
    if (ret) {
	warning(_("clipboard cannot be opened or contains no text"));
	res = FALSE;
    } else {
	XFree(buffer);
	if (pty_format != 8) { /* bytes */
	    warning(_("clipboard cannot be opened or contains no text"));
	    res = FALSE;
	} else { /* read the property */
	    ret = XGetWindowProperty(display, clpwin, pty, 0, (long)pty_size, False,
				     AnyPropertyType, &pty_type, &pty_format,
				     &pty_items, &pty_size, &buffer);
	    if (ret) {
		warning(_("clipboard cannot be read (error code %d)"), ret);
		res = FALSE;
	    } else {
		this->buff = (char *)malloc(pty_items + 1);
		this->last = this->len = (int) pty_items;
		if(this->buff) {
		    /* property always ends in 'extra' zero byte */
		    memcpy(this->buff, buffer, pty_items + 1);
		} else {
		    warning(_("memory allocation to copy clipboard failed"));
		    res = FALSE;
		}
		XFree(buffer);
	    }
	}
    }
    
    XDeleteProperty(display, clpwin, pty);
    if (!displayOpen) {
	XCloseDisplay(display);
	strcpy(dspname, "");
    }
    return res;
}

#include <R_ext/Rdynload.h>

extern const char * in_R_pngVersion(void);
extern const char * in_R_jpegVersion(void);
extern const char * in_R_tiffVersion(void);

void R_init_R_X11(DllInfo *info)
{
    R_X11Routines *tmp;
    tmp = (R_X11Routines*) malloc(sizeof(R_X11Routines));
    if(!tmp) {
	error(_("cannot allocate memory for X11Routines structure"));
	return;
    }
    tmp->X11 = in_do_X11;
    tmp->saveplot = in_do_saveplot;
    tmp->image = in_R_GetX11Image;
    tmp->access = in_R_X11_access;
    tmp->readclp = in_R_X11readclp;
    tmp->R_pngVersion = in_R_pngVersion;
    tmp->R_jpegVersion = in_R_jpegVersion;
    tmp->R_tiffVersion = in_R_tiffVersion;
    R_setX11Routines(tmp);
}
