int selectDevice(int devNum) { /* Valid to select nullDevice, but that will open a new device. See ?dev.set. */ if((devNum >= 0) && (devNum < R_MaxDevices) && (R_Devices[devNum] != NULL) && active[devNum]) { pGEDevDesc gdd; if (!NoDevices()) { pGEDevDesc oldd = GEcurrentDevice(); if (oldd->dev->deactivate) oldd->dev->deactivate(oldd->dev); } R_CurrentDevice = devNum; /* maintain .Device */ gsetVar(R_DeviceSymbol, elt(getSymbolValue(R_DevicesSymbol), devNum), R_BaseEnv); gdd = GEcurrentDevice(); /* will start a device if current is null */ if (!NoDevices()) /* which it always will be */ if (gdd->dev->activate) gdd->dev->activate(gdd->dev); return devNum; } else return selectDevice(nextDevice(devNum)); }
void attribute_hidden InitGraphics(void) { R_Devices[0] = &nullDevice; active[0] = TRUE; // these are static arrays, not really needed for (int i = 1; i < R_MaxDevices; i++) { R_Devices[i] = NULL; active[i] = FALSE; } /* init .Device and .Devices */ SEXP s = PROTECT(mkString("null device")); gsetVar(R_DeviceSymbol, s, R_BaseEnv); s = PROTECT(mkString("null device")); gsetVar(R_DevicesSymbol, CONS(s, R_NilValue), R_BaseEnv); UNPROTECT(2); }
/* historically the close was in the [kK]illDevices. only use findNext = FALSE when shutting R dowm, and .Device[s] are not updated. */ static void removeDevice(int devNum, Rboolean findNext) { /* Not vaild to remove nullDevice */ if((devNum > 0) && (devNum < R_MaxDevices) && (R_Devices[devNum] != NULL) && active[devNum]) { int i; SEXP s; pGEDevDesc g = R_Devices[devNum]; active[devNum] = FALSE; /* stops it being selected again */ R_NumDevices--; if(findNext) { /* maintain .Devices */ PROTECT(s = getSymbolValue(R_DevicesSymbol)); for (i = 0; i < devNum; i++) s = CDR(s); SETCAR(s, mkString("")); UNPROTECT(1); /* determine new current device */ if (devNum == R_CurrentDevice) { R_CurrentDevice = nextDevice(R_CurrentDevice); /* maintain .Device */ gsetVar(R_DeviceSymbol, elt(getSymbolValue(R_DevicesSymbol), R_CurrentDevice), R_BaseEnv); /* activate new current device */ if (R_CurrentDevice) { pGEDevDesc gdd = GEcurrentDevice(); if(gdd->dev->activate) gdd->dev->activate(gdd->dev); } } } g->dev->close(g->dev); GEdestroyDevDesc(g); R_Devices[devNum] = NULL; } }
/* convenience wrapper */ void GEaddDevice2(pGEDevDesc gdd, const char *name) { gsetVar(R_DeviceSymbol, mkString(name), R_BaseEnv); GEaddDevice(gdd); GEinitDisplayList(gdd); }
SEXP Quartz(SEXP args) { NewDevDesc *dev = NULL; GEDevDesc *dd; char *display, *vmax, *family=NULL; char fontfamily[255]; double height, width, ps; Rboolean antialias, autorefresh; SInt32 macVer; int quartzpos = 1; vmax = vmaxget(); args = CDR(args); /* skip entry point name */ display = CHAR(asChar(CAR(args))); args = CDR(args); width = asReal(CAR(args)); args = CDR(args); height = asReal(CAR(args)); args = CDR(args); if (width <= 0 || height <= 0) error(_("invalid width or height in quartz")); ps = asReal(CAR(args)); args = CDR(args); family = CHAR(asChar(CAR(args))); args = CDR(args); antialias = asLogical(CAR(args)); args = CDR(args); autorefresh = asLogical(CAR(args)); if(Gestalt(gestaltSystemVersion, &macVer) == noErr) if (macVer >= 0x1030) WeAreOnPanther = true; else WeAreOnPanther = false; R_CheckDeviceAvailable(); /* Allocate and initialize the device driver data */ BEGIN_SUSPEND_INTERRUPTS { if (!(dev = (NewDevDesc *) calloc(1, sizeof(NewDevDesc)))) return 0; /* Do this for early redraw attempts */ dev->displayList = R_NilValue; /* Make sure that this is initialised before a GC can occur. * This (and displayList) get protected during GC */ dev->savedSnapshot = R_NilValue; strcpy(fontfamily, family); #ifdef HAVE_AQUA if(useaqua) GetQuartzParameters(&width, &height, &ps, fontfamily, &antialias, &autorefresh, &quartzpos); #endif if (!QuartzDeviceDriver((DevDesc *)dev, display, width, height, ps, fontfamily, antialias, autorefresh, quartzpos, 0xffffffff)) { free(dev); error(_("unable to start device Quartz")); } gsetVar(install(".Device"), mkString("quartz"), R_NilValue); dd = GEcreateDevDesc(dev); addDevice((DevDesc*)dd); GEinitDisplayList(dd); } END_SUSPEND_INTERRUPTS; vmaxset(vmax); return R_NilValue; }