The R Project SVN R

Rev

Rev 87075 | Details | Compare with Previous | Last modification | View Log | RSS feed

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