CXXR (C++ R) API
GraphicsDevice.h
1 /*CXXR $Id: GraphicsDevice.h 1348 2013-02-25 17:49:03Z arr $
2  *CXXR
3  *CXXR This file is part of CXXR, a project to refactor the R interpreter
4  *CXXR into C++. It may consist in whole or in part of program code and
5  *CXXR documentation taken from the R project itself, incorporated into
6  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
7  *CXXR Licence.
8  *CXXR
9  *CXXR CXXR is Copyright (C) 2008-13 Andrew R. Runnalls, subject to such other
10  *CXXR copyrights and copyright restrictions as may be stated below.
11  *CXXR
12  *CXXR CXXR is not part of the R project, and bugs and other issues should
13  *CXXR not be reported via r-bugs or other R project channels; instead refer
14  *CXXR to the CXXR website.
15  *CXXR */
16 
17 /*
18  * R : A Computer Language for Statistical Data Analysis
19  * Copyright (C) 2001-11 The R Core Team.
20  *
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU Lesser General Public License as published by
23  * the Free Software Foundation; either version 2.1 of the License, or
24  * (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29  * GNU Lesser General Public License for more details.
30  *
31  * You should have received a copy of the GNU Lesser General Public License
32  * along with this program; if not, a copy is available at
33  * http://www.r-project.org/Licenses/
34  */
35 
36 /* Used by third-party graphics devices.
37  *
38  * This defines DevDesc, whereas GraphicsEngine.h defines GEDevDesc.
39  * Also contains entry points from gevents.c
40  */
41 
42 #ifndef R_GRAPHICSDEVICE_H_
43 #define R_GRAPHICSDEVICE_H_
44 
45 /*#include <R_ext/GraphicsContext.h>*/
46 #include "CXXR/RObject.h"
47 
48 /* ideally we would use prototypes in DevDesc.
49  Some devices have taken to passing pointers to their own structure
50  instead of DevDesc* , defining R_USE_PROTOTYPES 0 allows them to
51  opt out.
52 */
53 
54 #ifndef R_USE_PROTOTYPES
55 # define R_USE_PROTOTYPES 1
56 # ifndef R_GRAPHICSENGINE_H_
57 # error R_ext/GraphicsEngine.h must be included first, and includes this header
58 # endif
59 #endif
60 
61 #include <R_ext/Boolean.h>
62 
63 #ifdef __cplusplus
64 extern "C" {
65 #endif
66 
67 /* --------- New (in 1.4.0) device driver structure ---------
68  * NOTES:
69  * 1. All locations and dimensions are in device coordinates.
70  * 2. I found this comment in the doc for dev_Open -- looks nasty
71  * Any known instances of such a thing happening? Should be
72  * replaced by a function to query the device for preferred gpars
73  * settings? (to be called when the device is initialised)
74  *
75  * NOTE that it is perfectly acceptable for this
76  * function to set generic graphics parameters too
77  * (i.e., override the generic parameter settings
78  * which GInit sets up) all at the author's own risk
79  * of course :)
80  *
81  * 3. Do we really need dev_StrWidth as well as dev_MetricInfo?
82  * I can see the difference between the two -- its just a
83  * question of whether dev_MetricInfo should just return
84  * what dev_StrWidth would give if font metric information is
85  * not available. I guess having both allows the developer
86  * to decide when to ask for which sort of value, and to decide
87  * what to do when font metric information is not available.
88  * And why not a dev_StrHeight?
89  * 4. Should "ipr", "asp", and "cra" be in the device description?
90  * If not, then where?
91  * I guess they don't need to be if no device makes use of them.
92  * On the other hand, they would need to be replaced by a device
93  * call that R base graphics could use to get enough information
94  * to figure them out. (e.g., some sort of dpi() function to
95  * complement the size() function.)
96  */
97 
98 typedef struct _DevDesc DevDesc;
99 typedef DevDesc* pDevDesc;
100 
101 struct _DevDesc {
102  /********************************************************
103  * Device physical characteristics
104  ********************************************************/
105  double left; /* left raster coordinate */
106  double right; /* right raster coordinate */
107  double bottom; /* bottom raster coordinate */
108  double top; /* top raster coordinate */
109  /* R only has the notion of a rectangular clipping region
110  */
111  double clipLeft;
112  double clipRight;
113  double clipBottom;
114  double clipTop;
115  /* I hate these next three -- they seem like a real fudge
116  * BUT I'm not sure what to replace them with so they stay for now.
117  */
118  double xCharOffset; /* x character addressing offset - unused */
119  double yCharOffset; /* y character addressing offset */
120  double yLineBias; /* 1/2 interline space as frac of line height */
121  double ipr[2]; /* Inches per raster; [0]=x, [1]=y */
122  /* I hate this guy too -- seems to assume that a device can only
123  * have one font size during its lifetime
124  * BUT removing/replacing it would take quite a lot of work
125  * to design and insert a good replacement so it stays for now.
126  */
127  double cra[2]; /* Character size in rasters; [0]=x, [1]=y */
128  double gamma; /* (initial) Device Gamma Correction */
129  /********************************************************
130  * Device capabilities
131  ********************************************************/
132  Rboolean canClip; /* Device-level clipping */
133  Rboolean canChangeGamma; /* can the gamma factor be modified? */
134  int canHAdj; /* Can do at least some horiz adjust of text
135  0 = none, 1 = {0,0.5,1}, 2 = [0,1] */
136  /********************************************************
137  * Device initial settings
138  ********************************************************/
139  /* These are things that the device must set up when it is created.
140  * The graphics system can modify them and track current values,
141  */
142  double startps;
143  int startcol; /* sets par("fg"), par("col") and gpar("col") */
144  int startfill; /* sets par("bg") and gpar("fill") */
145  int startlty;
146  int startfont;
147  double startgamma;
148  /********************************************************
149  * Device specific information
150  ********************************************************/
151  void *deviceSpecific; /* pointer to device specific parameters */
152  /********************************************************
153  * Device display list
154  ********************************************************/
155  Rboolean displayListOn; /* toggle for initial display list status */
156 
157 
158  /********************************************************
159  * Event handling entries
160  ********************************************************/
161 
162  /* Used in do_setGraphicsEventEnv */
163 
164  Rboolean canGenMouseDown; /* can the device generate mousedown events */
165  Rboolean canGenMouseMove; /* can the device generate mousemove events */
166  Rboolean canGenMouseUp; /* can the device generate mouseup events */
167  Rboolean canGenKeybd; /* can the device generate keyboard events */
168 
169  Rboolean gettingEvent; /* This is set while getGraphicsEvent
170  is actively looking for events */
171 
172  /********************************************************
173  * Device procedures.
174  ********************************************************/
175 
176  /*
177  * ---------------------------------------
178  * GENERAL COMMENT ON GRAPHICS PARAMETERS:
179  * ---------------------------------------
180  * Graphical parameters are now passed in a pointer to a
181  * graphics context structure (pGEcontext) rather than individually.
182  * Each device action should extract the parameters it needs
183  * and ignore the others. Thought should be given to which
184  * parameters are relevant in each case -- the graphics engine
185  * does not REQUIRE that each parameter is honoured, but if
186  * a parameter is NOT honoured, it might be a good idea to
187  * issue a warning when a parameter is not honoured (or at
188  * the very least document which parameters are not honoured
189  * in the user-level documentation for the device). [An example
190  * of a parameter that may not be honoured by many devices is
191  * transparency.]
192  */
193 
194  /*
195  * device_Activate is called when a device becomes the
196  * active device. For example, it can be used to change the
197  * title of a window to indicate the active status of
198  * the device to the user. Not all device types will
199  * do anything.
200  * The only parameter is a device driver structure.
201  * An example is ...
202  *
203  * static void X11_Activate(pDevDesc dd);
204  *
205  * As from R 2.14.0 this can be omitted or set to NULL.
206  */
207 #if R_USE_PROTOTYPES
208  void (*activate)(const pDevDesc );
209 #else
210  void (*activate)();
211 #endif
212  /*
213  * device_Circle should have the side-effect that a
214  * circle is drawn, centred at the given location, with
215  * the given radius.
216  * (If the device has non-square pixels, 'radius' should
217  * be interpreted in the units of the x direction.)
218  * The border of the circle should be
219  * drawn in the given "col", and the circle should be
220  * filled with the given "fill" colour.
221  * If "col" is NA_INTEGER then no border should be drawn
222  * If "fill" is NA_INTEGER then the circle should not
223  * be filled.
224  * An example is ...
225  *
226  * static void X11_Circle(double x, double y, double r,
227  * pGEcontext gc,
228  * pDevDesc dd);
229  *
230  * R_GE_gcontext parameters that should be honoured (if possible):
231  * col, fill, gamma, lty, lwd
232  */
233 #if R_USE_PROTOTYPES
234  void (*circle)(double x, double y, double r, const pGEcontext gc, pDevDesc dd);
235 #else
236  void (*circle)();
237 #endif
238  /*
239  * device_Clip is given the left, right, bottom, and
240  * top of a rectangle (in DEVICE coordinates).
241  * It should have the side-effect that subsequent output
242  * is clipped to the given rectangle.
243  * NOTE that R's graphics engine already clips to the
244  * extent of the device.
245  * NOTE also that this will probably only be called if
246  * the flag canClip is true.
247  * An example is ...
248  *
249  * static void X11_Clip(double x0, double x1, double y0, double y1,
250  * pDevDesc dd)
251  */
252 #if R_USE_PROTOTYPES
253  void (*clip)(double x0, double x1, double y0, double y1, pDevDesc dd);
254 #else
255  void (*clip)();
256 #endif
257  /*
258  * device_Close is called when the device is killed.
259  * This function is responsible for destroying any
260  * device-specific resources that were created in
261  * device_Open and for FREEing the device-specific
262  * parameters structure.
263  * An example is ...
264  *
265  * static void X11_Close(pDevDesc dd)
266  *
267  */
268 #if R_USE_PROTOTYPES
269  void (*close)(pDevDesc dd);
270 #else
271  void (*close)();
272 #endif
273  /*
274  * device_Deactivate is called when a device becomes
275  * inactive.
276  * This allows the device to undo anything it did in
277  * dev_Activate.
278  * Not all device types will do anything.
279  * An example is ...
280  *
281  * static void X11_Deactivate(pDevDesc dd)
282  *
283  * As from R 2.14.0 this can be omitted or set to NULL.
284  */
285 #if R_USE_PROTOTYPES
286  void (*deactivate)(pDevDesc );
287 #else
288  void (*deactivate)();
289 #endif
290 
291 
292  /*
293  * device_Locator should return the location of the next
294  * mouse click (in DEVICE coordinates)
295  * Not all devices will do anything (e.g., postscript)
296  * An example is ...
297  *
298  * static Rboolean X11_Locator(double *x, double *y, pDevDesc dd)
299  *
300  * As from R 2.14.0 this can be omitted or set to NULL.
301  */
302 #if R_USE_PROTOTYPES
303  Rboolean (*locator)(double *x, double *y, pDevDesc dd);
304 #else
305  Rboolean (*locator)();
306 #endif
307  /*
308  * device_Line should have the side-effect that a single
309  * line is drawn (from x1,y1 to x2,y2)
310  * An example is ...
311  *
312  * static void X11_Line(double x1, double y1, double x2, double y2,
313  * const pGEcontext gc,
314  * pDevDesc dd);
315  *
316  * R_GE_gcontext parameters that should be honoured (if possible):
317  * col, gamma, lty, lwd
318  */
319 #if R_USE_PROTOTYPES
320  void (*line)(double x1, double y1, double x2, double y2,
321  const pGEcontext gc, pDevDesc dd);
322 #else
323  void (*line)();
324 #endif
325  /*
326  * device_MetricInfo should return height, depth, and
327  * width information for the given character in DEVICE
328  * units.
329  * Note: in an 8-bit locale, c is 'char'.
330  * In an mbcslocale, it is wchar_t, and at least some
331  * of code assumes that is UCS-2 (Windows, true) or UCS-4.
332  * This is used for formatting mathematical expressions
333  * and for exact centering of text (see GText)
334  * If the device cannot provide metric information then
335  * it MUST return 0.0 for ascent, descent, and width.
336  * An example is ...
337  *
338  * static void X11_MetricInfo(int c,
339  * const pGEcontext gc,
340  * double* ascent, double* descent,
341  * double* width, pDevDesc dd);
342  *
343  * R_GE_gcontext parameters that should be honoured (if possible):
344  * font, cex, ps
345  */
346 #if R_USE_PROTOTYPES
347  void (*metricInfo)(int c, const pGEcontext gc,
348  double* ascent, double* descent, double* width,
349  pDevDesc dd);
350 #else
351  void (*metricInfo)();
352 #endif
353  /*
354  * device_Mode is called whenever the graphics engine
355  * starts drawing (mode=1) or stops drawing (mode=0)
356  * GMode (in graphics.c) also says that
357  * mode = 2 (graphical input on) exists.
358  * The device is not required to do anything
359  * An example is ...
360  *
361  * static void X11_Mode(int mode, pDevDesc dd);
362  *
363  * As from R 2.14.0 this can be omitted or set to NULL.
364  */
365 #if R_USE_PROTOTYPES
366  void (*mode)(int mode, pDevDesc dd);
367 #else
368  void (*mode)();
369 #endif
370  /*
371  * device_NewPage is called whenever a new plot requires
372  * a new page.
373  * A new page might mean just clearing the
374  * device (e.g., X11) or moving to a new page
375  * (e.g., postscript)
376  * An example is ...
377  *
378  *
379  * static void X11_NewPage(const pGEcontext gc,
380  * pDevDesc dd);
381  *
382  */
383 #if R_USE_PROTOTYPES
384  void (*newPage)(const pGEcontext gc, pDevDesc dd);
385 #else
386  void (*newPage)();
387 #endif
388  /*
389  * device_Polygon should have the side-effect that a
390  * polygon is drawn using the given x and y values
391  * the polygon border should be drawn in the "col"
392  * colour and filled with the "fill" colour.
393  * If "col" is NA_INTEGER don't draw the border
394  * If "fill" is NA_INTEGER don't fill the polygon
395  * An example is ...
396  *
397  * static void X11_Polygon(int n, double *x, double *y,
398  * const pGEcontext gc,
399  * pDevDesc dd);
400  *
401  * R_GE_gcontext parameters that should be honoured (if possible):
402  * col, fill, gamma, lty, lwd
403  */
404 #if R_USE_PROTOTYPES
405  void (*polygon)(int n, const double *x, const double *y, const pGEcontext gc, pDevDesc dd);
406 #else
407  void (*polygon)();
408 #endif
409  /*
410  * device_Polyline should have the side-effect that a
411  * series of line segments are drawn using the given x
412  * and y values.
413  * An example is ...
414  *
415  * static void X11_Polyline(int n, double *x, double *y,
416  * const pGEcontext gc,
417  * pDevDesc dd);
418  *
419  * R_GE_gcontext parameters that should be honoured (if possible):
420  * col, gamma, lty, lwd
421  */
422 #if R_USE_PROTOTYPES
423  void (*polyline)(int n, const double *x, const double *y, const pGEcontext gc, pDevDesc dd);
424 #else
425  void (*polyline)();
426 #endif
427  /*
428  * device_Rect should have the side-effect that a
429  * rectangle is drawn with the given locations for its
430  * opposite corners. The border of the rectangle
431  * should be in the given "col" colour and the rectangle
432  * should be filled with the given "fill" colour.
433  * If "col" is NA_INTEGER then no border should be drawn
434  * If "fill" is NA_INTEGER then the rectangle should not
435  * be filled.
436  * An example is ...
437  *
438  * static void X11_Rect(double x0, double y0, double x1, double y1,
439  * const pGEcontext gc,
440  * pDevDesc dd);
441  *
442  */
443 #if R_USE_PROTOTYPES
444  void (*rect)(double x0, double y0, double x1, double y1,
445  const pGEcontext gc, pDevDesc dd);
446 #else
447  void (*rect)();
448 #endif
449  /*
450  * device_Path should draw one or more sets of points
451  * as a single path
452  *
453  * 'x' and 'y' give the points
454  *
455  * 'npoly' gives the number of polygons in the path
456  * MUST be at least 1
457  *
458  * 'nper' gives the number of points in each polygon
459  * each value MUST be at least 2
460  *
461  * 'winding' says whether to fill using the nonzero
462  * winding rule or the even-odd rule
463  *
464  * Added 2010-06-27
465  *
466  * As from R 2.13.2 this can be left unimplemented as NULL.
467  */
468 #if R_USE_PROTOTYPES
469  void (*path)(double *x, double *y,
470  int npoly, int *nper,
471  Rboolean winding,
472  const pGEcontext gc, pDevDesc dd);
473 #else
474  void (*path)();
475 #endif
476  /*
477  * device_Raster should draw a raster image justified
478  * at the given location,
479  * size, and rotation (not all devices may be able to rotate?)
480  *
481  * 'raster' gives the image data BY ROW, with every four bytes
482  * giving one R colour (ABGR).
483  *
484  * 'x and 'y' give the bottom-left corner.
485  *
486  * 'rot' is in degrees (as per device_Text), with positive
487  * rotation anticlockwise from the positive x-axis.
488  *
489  * As from R 2.13.2 this can be left unimplemented as NULL.
490  */
491 #if R_USE_PROTOTYPES
492  void (*raster)(unsigned int *raster, int w, int h,
493  double x, double y,
494  double width, double height,
495  double rot,
496  Rboolean interpolate,
497  const pGEcontext gc, pDevDesc dd);
498 #else
499  void (*raster)();
500 #endif
501  /*
502  * device_Cap should return an integer matrix (R colors)
503  * representing the current contents of the device display.
504  *
505  * The result is expected to be ROW FIRST.
506  *
507  * This will only make sense for raster devices and can
508  * probably only be implemented for screen devices.
509  *
510  * added 2010-06-27
511  *
512  * As from R 2.13.2 this can be left unimplemented as NULL.
513  * For earlier versions of R it should return R_NilValue.
514  */
515 #if R_USE_PROTOTYPES
516  SEXP (*cap)(pDevDesc dd);
517 #else
518  SEXP (*cap)();
519 #endif
520  /*
521  * device_Size is called whenever the device is
522  * resized.
523  * The function returns (left, right, bottom, and top) for the
524  * new device size.
525  * This is not usually called directly by the graphics
526  * engine because the detection of device resizes
527  * (e.g., a window resize) are usually detected by
528  * device-specific code.
529  * An example is ...
530  *
531  * static void X11_Size(double *left, double *right,
532  * double *bottom, double *top,
533  * pDevDesc dd);
534  *
535  * R_GE_gcontext parameters that should be honoured (if possible):
536  * col, fill, gamma, lty, lwd
537  *
538  * As from R 2.13.2 this can be left unimplemented as NULL.
539  */
540 #if R_USE_PROTOTYPES
541  void (*size)(double *left, double *right, double *bottom, double *top,
542  pDevDesc dd);
543 #else
544  void (*size)();
545 #endif
546  /*
547  * device_StrWidth should return the width of the given
548  * string in DEVICE units.
549  * An example is ...
550  *
551  * static double X11_StrWidth(const char *str,
552  * const pGEcontext gc,
553  * pDevDesc dd)
554  *
555  * R_GE_gcontext parameters that should be honoured (if possible):
556  * font, cex, ps
557  */
558 #if R_USE_PROTOTYPES
559  double (*strWidth)(const char *str, const pGEcontext gc, pDevDesc dd);
560 #else
561  double (*strWidth)();
562 #endif
563  /*
564  * device_Text should have the side-effect that the
565  * given text is drawn at the given location.
566  * The text should be rotated according to rot (degrees)
567  * An example is ...
568  *
569  * static void X11_Text(double x, double y, const char *str,
570  * double rot, double hadj,
571  * const pGEcontext gc,
572  * pDevDesc dd);
573  *
574  * R_GE_gcontext parameters that should be honoured (if possible):
575  * font, cex, ps, col, gamma
576  */
577 #if R_USE_PROTOTYPES
578  void (*text)(double x, double y, const char *str, double rot,
579  double hadj, const pGEcontext gc, pDevDesc dd);
580 #else
581  void (*text)();
582 #endif
583  /*
584  * device_onExit is called by GEonExit when the user has aborted
585  * some operation, and so an R_ProcessEvents call may not return normally.
586  * It need not be set to any value; if null, it will not be called.
587  *
588  * An example is ...
589  *
590  * static void GA_onExit(pDevDesc dd);
591  */
592 #if R_USE_PROTOTYPES
593  void (*onExit)(pDevDesc dd);
594 #else
595  void (*onExit)(struct _NewDevDesc*);
596 #endif
597  /*
598  * device_getEvent is no longer used, but the slot is kept for back
599  * compatibility of the structure.
600  */
601  SEXP (*getEvent)(SEXP, const char *);
602 
603  /* --------- Optional features introduced in 2.7.0 --------- */
604 
605  /* Does the device have a device-specific way to confirm a
606  new frame (for e.g. par(ask=TRUE))?
607  This should be NULL if it does not.
608  If it does, it returns TRUE if the device handled this, and
609  FALSE if it wants the engine to do so.
610 
611  There is an example in the windows() device.
612 
613  Can be left unimplemented as NULL.
614  */
615 #if R_USE_PROTOTYPES
616  Rboolean (*newFrameConfirm)(pDevDesc dd);
617 #else
618  Rboolean (*newFrameConfirm)();
619 #endif
620 
621  /* Some devices can plot UTF-8 text directly without converting
622  to the native encoding, e.g. windows(), quartz() ....
623 
624  If this flag is true, all text *not in the symbol font* is sent
625  in UTF8 to the textUTF8/strWidthUTF8 entry points.
626 
627  If the flag is TRUE, the metricInfo entry point should
628  accept negative values for 'c' and treat them as indicating
629  Unicode points (as well as positive values in a MBCS locale).
630  */
631  Rboolean hasTextUTF8; /* and strWidthUTF8 */
632 #if R_USE_PROTOTYPES
633  void (*textUTF8)(double x, double y, const char *str, double rot,
634  double hadj, const pGEcontext gc, pDevDesc dd);
635  double (*strWidthUTF8)(const char *str, const pGEcontext gc, pDevDesc dd);
636 #else
637  void (*textUTF8)();
638  double (*strWidthUTF8)();
639 #endif
640  Rboolean wantSymbolUTF8;
641 
642  /* Is rotated text good enough to be preferable to Hershey in
643  contour labels? Old default was FALSE.
644  */
645  Rboolean useRotatedTextInContour;
646 
647  /* --------- Post-2.7.0 features --------- */
648 
649  /* Added in 2.12.0: Changed graphics event handling. */
650 
651  SEXP eventEnv; /* This is an environment holding event handlers. */
652  /*
653  * eventHelper(dd, 1) is called by do_getGraphicsEvent before looking for a
654  * graphics event. It will then call R_ProcessEvents() and eventHelper(dd, 2)
655  * until this or another device returns sets a non-null result value in eventEnv,
656  * at which time eventHelper(dd, 0) will be called.
657  *
658  * An example is ...
659  *
660  * static SEXP GA_eventHelper(pDevDesc dd, int code);
661 
662  * Can be left unimplemented as NULL
663  */
664 #if R_USE_PROTOTYPES
665  void (*eventHelper)(pDevDesc dd, int code);
666 #else
667  void (*eventHelper)();
668 #endif
669 
670  /* added in 2.14.0, only used by screen devices.
671 
672  Allows graphics devices to have multiple levels of suspension:
673  when this reaches zero output is flushed.
674 
675  Can be left unimplemented as NULL.
676  */
677 #if R_USE_PROTOTYPES
678  int (*holdflush)(pDevDesc dd, int level);
679 #else
680  int (*holdflush)();
681 #endif
682 
683  /* added in 2.14.0, for dev.capabilities.
684  In all cases 0 means NA (unset).
685  */
686  int haveTransparency; /* 1 = no, 2 = yes */
687  int haveTransparentBg; /* 1 = no, 2 = fully, 3 = semi */
688  int haveRaster; /* 1 = no, 2 = yes, 3 = except for missing values */
689  int haveCapture, haveLocator; /* 1 = no, 2 = yes */
690 
691 
692  /* Area for future expansion.
693  By zeroing this, devices are more likely to work if loaded
694  into a later version of R than that they were compiled under.
695  */
696  char reserved[64];
697 };
698 
699 
700  /********************************************************/
701  /* the device-driver entry point is given a device */
702  /* description structure that it must set up. this */
703  /* involves several important jobs ... */
704  /* (1) it must ALLOCATE a new device-specific parameters*/
705  /* structure and FREE that structure if anything goes */
706  /* wrong (i.e., it won't report a successful setup to */
707  /* the graphics engine (the graphics engine is NOT */
708  /* responsible for allocating or freeing device-specific*/
709  /* resources or parameters) */
710  /* (2) it must initialise the device-specific resources */
711  /* and parameters (mostly done by calling device_Open) */
712  /* (3) it must initialise the generic graphical */
713  /* parameters that are not initialised by GInit (because*/
714  /* only the device knows what values they should have) */
715  /* see Graphics.h for the official list of these */
716  /* (4) it may reset generic graphics parameters that */
717  /* have already been initialised by GInit (although you */
718  /* should know what you are doing if you do this) */
719  /* (5) it must attach the device-specific parameters */
720  /* structure to the device description structure */
721  /* e.g., dd->deviceSpecfic = (void *) xd; */
722  /* (6) it must FREE the overall device description if */
723  /* it wants to bail out to the top-level */
724  /* the graphics engine is responsible for allocating */
725  /* the device description and freeing it in most cases */
726  /* but if the device driver freaks out it needs to do */
727  /* the clean-up itself */
728  /********************************************************/
729 
730 /* moved from Rgraphics.h */
731 
732 /*
733  * Some Notes on Color
734  *
735  * R uses a 24-bit color model. Colors are specified in 32-bit
736  * integers which are partitioned into 4 bytes as follows.
737  *
738  * <-- most sig least sig -->
739  * +-------------------------------+
740  * | 0 | blue | green | red |
741  * +-------------------------------+
742  *
743  * The red, green and blue bytes can be extracted as follows.
744  *
745  * red = ((color ) & 255)
746  * green = ((color >> 8) & 255)
747  * blue = ((color >> 16) & 255)
748  */
749 /*
750  * Changes as from 1.4.0: use top 8 bits as an alpha channel.
751  * 0 = opaque, 255 = transparent.
752  */
753 /*
754  * Changes as from 2.0.0: use top 8 bits as full alpha channel
755  * 255 = opaque, 0 = transparent
756  * [to conform with SVG, PDF and others]
757  * and everything in between is used
758  * [which means that NA is not stored as an internal colour;
759  * it is converted to R_RGBA(255, 255, 255, 0)]
760  */
761 
762 #define R_RGB(r,g,b) ((r)|((g)<<8)|((b)<<16)|0xFF000000)
763 #define R_RGBA(r,g,b,a) ((r)|((g)<<8)|((b)<<16)|((a)<<24))
764 #define R_RED(col) (((col) )&255)
765 #define R_GREEN(col) (((col)>> 8)&255)
766 #define R_BLUE(col) (((col)>>16)&255)
767 #define R_ALPHA(col) (((col)>>24)&255)
768 #define R_OPAQUE(col) (R_ALPHA(col) == 255)
769 #define R_TRANSPARENT(col) (R_ALPHA(col) == 0)
770  /*
771  * A transparent white
772  */
773 #define R_TRANWHITE (R_RGBA(255, 255, 255, 0))
774 
775 
776 /* used in various devices */
777 
778 #define curDevice Rf_curDevice
779 #define killDevice Rf_killDevice
780 #define ndevNumber Rf_ndevNumber
781 #define NewFrameConfirm Rf_NewFrameConfirm
782 #define nextDevice Rf_nextDevice
783 #define NoDevices Rf_NoDevices
784 #define NumDevices Rf_NumDevices
785 #define prevDevice Rf_prevDevice
786 #define selectDevice Rf_selectDevice
787 #define AdobeSymbol2utf8 Rf_AdobeSymbol2utf8
788 
789 /* Properly declared version of devNumber */
790 int ndevNumber(pDevDesc );
791 
792 /* Formerly in Rdevices.h */
793 
794 /* How many devices exist ? (>= 1) */
795 int NumDevices(void);
796 
797 /* Check for an available device slot */
798 void R_CheckDeviceAvailable(void);
799 Rboolean R_CheckDeviceAvailableBool(void);
800 
801 /* Return the number of the current device. */
802 int curDevice(void);
803 
804 /* Return the number of the next device. */
805 int nextDevice(int);
806 
807 /* Return the number of the previous device. */
808 int prevDevice(int);
809 
810 /* Make the specified device (specified by number) the current device */
811 int selectDevice(int);
812 
813 /* Kill device which is identified by number. */
814 void killDevice(int);
815 
816 int NoDevices(void); /* used in engine, graphics, plot, grid */
817 
818 void NewFrameConfirm(pDevDesc); /* used in graphics.c, grid */
819 
820 
821 /* Graphics events: defined in gevents.c */
822 
823 /* These give the indices of some known keys */
824 
825 typedef enum {knUNKNOWN = -1,
826  knLEFT = 0, knUP, knRIGHT, knDOWN,
827  knF1, knF2, knF3, knF4, knF5, knF6, knF7, knF8, knF9, knF10,
828  knF11, knF12,
829  knPGUP, knPGDN, knEND, knHOME, knINS, knDEL} R_KeyName;
830 
831 /* These are the three possible mouse events */
832 
833 typedef enum {meMouseDown = 0,
834  meMouseUp,
835  meMouseMove} R_MouseEvent;
836 
837 #define leftButton 1
838 #define middleButton 2
839 #define rightButton 4
840 
841 #define doKeybd Rf_doKeybd
842 #define doMouseEvent Rf_doMouseEvent
843 
844 void doMouseEvent(pDevDesc dd, R_MouseEvent event,
845  int buttons, double x, double y);
846 void doKeybd(pDevDesc dd, R_KeyName rkey,
847  const char *keyname);
848 
849 
850 /* For use in third-party devices when setting up a device:
851  * duplicates Defn.h which is used internally.
852  * (Tested in devNull.c)
853  */
854 
855 #ifndef BEGIN_SUSPEND_INTERRUPTS
856 /* Macros for suspending interrupts */
857 #define BEGIN_SUSPEND_INTERRUPTS do { \
858  Rboolean __oldsusp__ = R_interrupts_suspended; \
859  R_interrupts_suspended = TRUE;
860 #define END_SUSPEND_INTERRUPTS R_interrupts_suspended = __oldsusp__; \
861  if (R_interrupts_pending && ! R_interrupts_suspended) \
862  Rf_onintr(); \
863 } while(0)
864 
865 #include <R_ext/libextern.h>
866 LibExtern Rboolean R_interrupts_suspended;
867 LibExtern int R_interrupts_pending;
868 extern void Rf_onintr(void);
869 LibExtern Rboolean mbcslocale;
870 #endif
871 
872 /* Useful for devices: translates Adobe symbol encoding to UTF-8 */
873 extern void *AdobeSymbol2utf8(char*out, const char *in, int nwork);
874 int Rf_AdobeSymbol2ucs2(int n); // arr 2008/07/10
875 /* Translates Unicode point to UTF-8 */
876 extern size_t Rf_ucstoutf8(char *s, const unsigned int c);
877 
878 #ifdef __cplusplus
879 }
880 #endif
881 
882 #endif /* R_GRAPHICSDEVICE_ */