The R Project SVN R

Rev

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