# this is a shar archive - extract by running sh on it cat > devX11.c << 'EnDoFtHiSbIt' /* * R : A Computer Langage for Statistical Data Analysis * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include #include #include #include #include "Graphics.h" #include "rotated.h" void error(char*); /* Start of Tunable Defaults */ #define CURSOR XC_crosshair /* Default cursor */ /* End of Tunable Defaults */ /* R Device Driver code */ /* Graphics Parameters for last driver call. */ static double cex = 1.0; static double srt = 0.0; static unsigned col = -1; static int lty = -1; static rcolor fg; static rcolor bg; static int windowWidth; static int windowHeight; static int resize = 0; static Display *display; /* Display */ static int screen; /* Screen */ static int depth; /* Pixmap depth */ static Window rootWindow; /* Root Window */ static Window window; /* Graphics Window */ static Cursor gcursor; /* Graphics Cursor */ static GC wgc; /* GC for window */ static XSetWindowAttributes attributes; /* Window attributes */ static XEvent event; /* Event */ static Colormap cmap; /* Default color map */ static XColor fgcolor; /* Foreground color */ static XColor bgcolor; /* Background color */ static int blackpixel; /* Black */ static int whitepixel; /* White */ static int fontface = -1; static int fontsize = -1; static int usefixed = 0; static void ProcessEvents(void); static void X11_NewPlot(void); /* ---- Utility Functions ---- */ #define MM_PER_INCH 25.4 static double pixelWidth(void) { double width, widthMM; width = DisplayWidth(display, screen); widthMM = DisplayWidthMM(display, screen); return (widthMM / width) / MM_PER_INCH; } static double pixelHeight(void) { double height, heightMM; height = DisplayHeight(display, screen); heightMM = DisplayHeightMM(display, screen); return (heightMM / height) / MM_PER_INCH; } /* Font information array. */ /* Point sizes: 6-24 */ /* Faces: plain, bold, oblique, bold-oblique */ /* Symbol may be added later */ #define NFONT 19 static XFontStruct *fontarray[NFONT][4] = { {NULL, NULL, NULL, NULL}, /* 6 */ {NULL, NULL, NULL, NULL}, /* 8 */ {NULL, NULL, NULL, NULL}, /* 10 */ {NULL, NULL, NULL, NULL}, /* 12 */ {NULL, NULL, NULL, NULL}, /* 14 */ {NULL, NULL, NULL, NULL}, /* 16 */ {NULL, NULL, NULL, NULL}, /* 18 */ {NULL, NULL, NULL, NULL}, /* 20 */ {NULL, NULL, NULL, NULL}, /* 22 */ {NULL, NULL, NULL, NULL}, /* 24 */ }; static int fontmissing[] = { 0, /* 6 */ 0, /* 8 */ 0, /* 10 */ 0, /* 12 */ 0, /* 14 */ 0, /* 16 */ 0, /* 18 */ 0, /* 20 */ 0, /* 22 */ 0, /* 24 */ }; #ifdef FIXED static char *fontname = "fixed"; #else static char *fontname = "-adobe-helvetica-%s-%s-*-*-%d-*-*-*-*-*-*-*"; #endif static char *slant[] = {"r", "o"}; static char *weight[] = {"medium", "bold"}; static XFontStruct *font; /* Find out if the X server has the base font */ /* If not try "fixed" and if that fails bail out */ static int SetBaseFont() { char buf[128]; fontface = 1; fontsize = GP->ps; sprintf(buf, fontname, weight[(fontface-1)%2], slant[((fontface-1)/2)%2], 12); fontarray[(fontsize-6)/2][fontface-1] = XLoadQueryFont(display, buf); if(!fontarray[(fontsize-6)/2][fontface-1]) { usefixed = 1; fontarray[(fontsize-6)/2][0] = XLoadQueryFont(display, "fixed"); if(!fontarray[fontsize-6][fontface-1]) return 0; fontarray[(fontsize-6)/2][1] = fontarray[(fontsize-6)/2][0]; fontarray[(fontsize-6)/2][2] = fontarray[(fontsize-6)/2][0]; fontarray[(fontsize-6)/2][3] = fontarray[(fontsize-6)/2][0]; } font = fontarray[(fontsize-6)/2][fontface-1]; return 1; } /* Set the font size and face */ /* If the font of this size and at that the specified */ /* rotation is not present it is loaded. */ /* 0 = plain text, 1 = bold */ /* 2 = oblique, 3 = bold-oblique */ static void SetFont(int face, int size) { char buf[128]; if(face < 1 || face > 4) face = 1; size = 2 * size / 2; if(size < 6) size = 6; if(size > 24) size = 24; if(!usefixed && (size != fontsize || face != fontface)) { if(fontarray[size-6][face-1] == NULL) { switch(size) { case 6: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; size += 2; case 8: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; size += 2; case 10: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; size += 2; case 12: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; fontarray[(size-6)/2][face-1] = fontarray[(size-6)/2][0]; break; case 24: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; case 22: case 20: size = 18; case 18: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; size -= 2; case 16: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; size -= 2; case 14: sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; size -= 2; sprintf(buf, fontname, weight[(face-1)%2], slant[((face-1)/2)%2], size); fontarray[(size-6)/2][face-1] = XLoadQueryFont(display, buf); if(fontarray[(size-6)/2][face-1]) break; fontarray[(size-6)/2][face-1] = fontarray[(size-6)/2][0]; break; } } font = fontarray[(size-6)/2][face-1]; fontface = face; fontsize = size; XSetFont(display, wgc, font->fid); } } static void SetColor(unsigned color) { if(color != col) { fgcolor.red = ((color >> 8) & 255) << 8; fgcolor.green = ((color >> 16) & 255) << 8; fgcolor.blue = ((color >> 24) & 255) << 8; if(XAllocColor(display, cmap, &fgcolor) == 0) error("color allocation error\n"); blackpixel = fgcolor.pixel; col = color; XSetState(display, wgc, blackpixel, whitepixel, GXcopy, AllPlanes); } } static void SetLinetype(unsigned newlty) { unsigned char dashlist[8]; int i, ndash; if(newlty != lty) { if(newlty == 0) { XSetLineAttributes(display, wgc, 1, LineSolid, CapRound, JoinRound); lty = newlty; } else { lty = newlty; ndash = 0; for(i=0 ; i<8 && newlty&15 ; i++) { dashlist[ndash++] = newlty&15; newlty = newlty>>4; } XSetDashes(display, wgc, 0, dashlist, ndash); XSetLineAttributes(display, wgc, 1, LineOnOffDash, CapRound, JoinRound); } } } static int X11_Open(char *dsp, double w, double h) { int iw, ih, result; XGCValues gcv; XColor exact; /* open the default display */ /* return value of 0 indicates failure */ if ((display = XOpenDisplay(dsp)) == NULL) return 0; if (!SetBaseFont()) { Rprintf("X11 font problem\n"); XCloseDisplay(display); return 0; } /* Default Screen and Root Window */ screen = XDefaultScreen(display); rootWindow = XDefaultRootWindow(display); depth = XDefaultDepth(display, screen); /* Foreground and Background Colors */ bg = DP->bg = GP->bg = RGB(255,255,255); fg = DP->fg = GP->fg = RGB(0,0,0); col = DP->col = GP->col = fg; cmap = DefaultColormap(display, screen); result = XAllocNamedColor(display, cmap, "white", &exact, &bgcolor); if (result == 0) error("color allocation error\n"); result = XAllocNamedColor(display, cmap, "black", &exact, &fgcolor); if (result == 0) error("color allocation error\n"); whitepixel = bgcolor.pixel; blackpixel = fgcolor.pixel; /* Try to create a simple window */ /* Want to know about exposures */ /* and window-resizes and locations */ attributes.background_pixel = whitepixel; attributes.border_pixel = blackpixel; attributes.backing_store = Always; attributes.event_mask = ButtonPressMask | ExposureMask | StructureNotifyMask; windowWidth = iw = w/pixelWidth(); windowHeight = ih = h/pixelHeight(); if ((window = XCreateWindow( display, rootWindow, DisplayWidth(display, screen) - iw - 10, 10, iw, ih, 1, DefaultDepth(display, screen), InputOutput, DefaultVisual(display, screen), CWEventMask | CWBackPixel | CWBorderPixel | CWBackingStore, &attributes)) == 0) return 0; XChangeProperty( display, window, XA_WM_NAME, XA_STRING, 8, PropModeReplace, "R Graphics", 13); gcursor = XCreateFontCursor(display, CURSOR); XDefineCursor(display, window, gcursor); /* map the window */ XSelectInput(display, window, ExposureMask | ButtonPressMask | StructureNotifyMask); XMapWindow(display, window); XSync(display, 0); /* gobble expose events */ XNextEvent(display, &event); if (event.xany.type == Expose) { while (event.xexpose.count) XNextEvent(display, &event); } /* set the graphics context */ gcv.arc_mode = ArcChord; wgc = XCreateGC(display, window, GCArcMode, &gcv); XSetState(display, wgc, blackpixel, whitepixel, GXcopy, AllPlanes); XSetFont(display, wgc, font->fid); SetLinetype(0); return 1; } static double X11_StrWidth(char *str) { int size = GP->cex * GP->ps + 0.5; SetFont(GP->font, size); return (double)XTextWidth(font, str, strlen(str)); } static XRectangle clip; static void X11_Clip(int x0, int x1, int y0, int y1) { if (x0 < x1) { clip.x = x0; clip.width = x1 - x0; } else { clip.x = x1; clip.width = x0 - x1; } if (y0 < y1) { clip.y = y0; clip.height = y1 - y0; } else { clip.y = y1; clip.height = y0 - y1; } XSetClipRectangles(display, wgc, 0, 0, &clip, 1, Unsorted); } static void X11_Resize() { ProcessEvents(); if (resize) { DP->left = 0.0; DP->right = windowWidth; DP->bottom = windowHeight; DP->top = 0.0; resize = 0; } } static void X11_NewPlot() { int result; if(bg != DP->bg) { bg = DP->bg; bgcolor.red = ((bg>> 8)&255)<<8; bgcolor.green = ((bg>>16)&255)<<8; bgcolor.blue = ((bg>>24)&255)<<8; result = XAllocColor(display, cmap, &bgcolor); if (result == 0) error("color allocation error\n"); whitepixel = bgcolor.pixel; XSetWindowBackground(display, window, whitepixel); } XClearWindow(display, window); XSync(display, 0); } static void X11_Close(void) { int i, j; /* Free Resources Here */ for(i=0 ; ifid); fontarray[i][j] = NULL; } XCloseDisplay(display); /* XVertEnd(); */ } static void X11_StartPath() { SetColor(GP->col); SetLinetype(GP->lty); } static void X11_EndPath() { } static int xlast; static int ylast; static void X11_MoveTo(int x, int y) { xlast = x; ylast = y; } static void X11_LineTo(int x, int y) { XDrawLine(display, window, wgc, xlast, ylast, x, y); xlast = x; ylast = y; XSync(display, 0); } static void X11_Rect(int x0, int y0, int x1, int y1, int fill) { int tmp; if (x0 > x1) { tmp = x0; x0 = x1; x1 = tmp; } if (y0 > y1) { tmp = y0; y0 = y1; y1 = tmp; } SetColor(GP->col); if (fill) XFillRectangle(display, window, wgc, x0, y0, x1 - x0, y1 - y0); else XDrawRectangle(display, window, wgc, x0, y0, x1 - x0, y1 - y0); XSync(display, 0); } static void X11_Circle(int x, int y, int r, int col, int border) { if(col != NA_INTEGER) { SetColor(col); XFillArc(display, window, wgc, x-r, y-r, 2*r, 2*r, 0, 23040); } if(border != NA_INTEGER) { SetLinetype(GP->lty); SetColor(border); XDrawArc(display, window, wgc, x-r, y-r, 2*r, 2*r, 0, 23040); } } static void X11_Polygon(int n, int *x, int *y) { XPoint *points; char *vmax, *vmaxget(); int i; if((points=(XPoint*)R_alloc(n, sizeof(XPoint))) == NULL) error("out of memory while drawing polygon\n"); for(i=0 ; icol); XFillPolygon(display, window, wgc, points, n, Complex, CoordModeOrigin); XSync(display, 0); vmaxset(vmax); } static double deg2rad = 0.01745329251994329576; static void X11_Text(char *str, int rot) { int len, size; size = GP->cex * GP->ps + 0.5; SetFont(GP->font, size); SetColor(GP->col); len = strlen(str); XRotDrawString(display, font, (double)rot, window, wgc, xlast, ylast, str); XSync(display, 0); } static int X11_Locator(int *x, int *y) { ProcessEvents(); /* discard pending events */ XSync(display, 1); XNextEvent(display, &event); if (event.xbutton.button == Button1 /* || event.xbutton.button==Button2 */ ) { *x = event.xbutton.x; *y = event.xbutton.y; fprintf(stderr, "\07"); fflush(stderr); XSync(display, 0); return 1; } else { XSync(display, 0); return 0; } } static void ProcessEvents(void) { while (XPending(display)) { XNextEvent(display, &event); if (event.xany.type == Expose) { while (event.xexpose.count) { XNextEvent(display, &event); } } else if (event.type == ConfigureNotify) { windowWidth = event.xconfigure.width; windowHeight = event.xconfigure.height; resize = 1; } } } /* Set Graphics mode - not needed for X11 */ static void X11_Mode(int mode) { if(mode == 0) XSync(display, 0); } /* Hold the Picture Onscreen - not needed for X11 */ static void X11_Hold() { } /* * The arguments to X11DeviceDriver are * cpars[0] = display name * npars[0] = width (inches) * npars[1] = height (inches) */ int X11DeviceDriver(char **cpars, int ncpars, double *npars, int nnpars) { DevInit = 0; if(ncpars != 1 || nnpars != 2) error("invalid device parameters (x11)\n"); /* Font will load at first use */ fontface = -1; fontsize = -1; GP->font = 1; GP->ps = 12; if (!X11_Open(cpars[0], npars[0], npars[1])) return 0; ProcessEvents(); DevOpen = X11_Open; DevClose = X11_Close; DevResize = X11_Resize; DevNewPlot = X11_NewPlot; DevClip = X11_Clip; DevStartPath = X11_StartPath; DevEndPath = X11_EndPath; DevMoveTo = X11_MoveTo; DevLineTo = X11_LineTo; DevStrWidth = X11_StrWidth; DevText = X11_Text; DevRect = X11_Rect; DevCircle = X11_Circle; DevPolygon = X11_Polygon; DevLocator = X11_Locator; DevMode = X11_Mode; DevHold = X11_Hold; /* Window Dimensions in Pixels */ GP->left = 0; /* left */ GP->right = windowWidth; /* right */ GP->bottom = windowHeight; /* bottom */ GP->top = 0; /* top */ /* Nominal Character Sizes in Pixels */ GP->cra[0] = font->max_bounds.rbearing - font->min_bounds.lbearing; GP->cra[1] = font->max_bounds.ascent + font->max_bounds.descent; /* Character Addressing Offsets */ /* These are used to plot a single plotting character */ /* so that it is exactly over the plotting point */ GP->xCharOffset = 0.4900; GP->yCharOffset = 0.3333; GP->yLineBias = 0.1; /* Inches per Raster Unit */ /* Using nominal 72dpi */ GP->ipr[0] = 1.0 / 72.0; GP->ipr[1] = 1.0 / 72.0; GP->canResizePlot = 1; GP->canChangeFont = 0; GP->canRotateText = 1; GP->canResizeText = 1; GP->canClip = 1; DevInit = 1; cex = 1.0; lty = 0; xlast = 250; ylast = 250; return 1; } EnDoFtHiSbIt cat > ginit.c << 'EnDoFtHiSbIt' /* * R : A Computer Langage for Statistical Data Analysis * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "Graphics.h" void GInit() { GP->ann = 1; GP->err = 0; GP->bty = 'o'; GP->cex = 1.0; GP->cexbase = 1.0; GP->cexmain = 1.2; GP->cexlab = 1.0; GP->cexsub = 1.0; GP->cexaxis = 1.0; GP->col = 0; GP->colmain = 0; GP->collab = 0; GP->colsub = 0; GP->colaxis = 0; /* GP->ps = 10; */ GP->font = 1; GP->fontmain = 2; GP->fontlab = 1; GP->fontsub = 1; GP->fontaxis = 1; GP->pch = 1; GP->lty = LTY_SOLID; GP->smo = 1; /* String Adjustment and rotation */ GP->adj = 0.5; GP->crt = 0.0; GP->srt = 0.0; /* Character extents are based on the raster size */ GP->asp = GP->ipr[1] / GP->ipr[0]; /* GP->cin[0] = GP->cra[0] * GP->ipr[0]; */ /* GP->cin[1] = GP->cra[1] * GP->ipr[1]; */ /* GP->csi = GP->cin[0]; */ GP->mkh = GP->cra[0] * GP->ipr[0]; /* Positioning of margin text */ GP->mgp[0] = 3; GP->mgp[1] = 1; GP->mgp[2] = 0; /* Axis annotation parameters */ GP->lab[0] = 5; GP->lab[1] = 5; GP->lab[2] = 7; GP->las = 0; GP->tck = -0.2; GP->tmag = 1.2; GP->type = 'p'; GP->xaxp[0] = 0.0; GP->xaxp[1] = 1.0; GP->xaxp[2] = 5.0; GP->xaxs = 'r'; GP->xaxt = 's'; GP->xlog = 0; GP->xpd = 0; GP->yaxp[0] = 0.0; GP->yaxp[1] = 1.0; GP->yaxp[2] = 5.0; GP->yaxs = 'r'; GP->yaxt = 's'; GP->ylog = 0; /* Outer Margins */ GP->mex = 1.0; GP->oma[0] = 0.0; GP->oma[1] = 0.0; GP->oma[2] = 0.0; GP->oma[3] = 0.0; GP->fig[0] = 0.0; GP->fig[1] = 1.0; GP->fig[2] = 0.0; GP->fig[3] = 1.0; /* Inner Margins */ GP->mar[0] = 5.1; GP->mar[1] = 4.1; GP->mar[2] = 4.1; GP->mar[3] = 2.1; /* Multi-figure parameters */ GP->mfind = 0; GP->mfg[0] = 1; GP->mfg[1] = 1; GP->mfg[2] = 1; GP->mfg[3] = 1; /* Misc plotting parameters */ GP->new = 0; GP->pty = 'm'; /* Data window */ GP->usr[0] = 0.0; GP->usr[1] = 1.0; GP->usr[2] = 0.0; GP->usr[3] = 1.0; GReset(); memcpy(DP, GP, sizeof(GPar)); } EnDoFtHiSbIt