The R Project SVN R

Rev

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