void GEaddDevice(pGEDevDesc gdd) { int i; Rboolean appnd; SEXP s, t; pGEDevDesc oldd; PROTECT(s = getSymbolValue(R_DevicesSymbol)); if (!NoDevices()) { oldd = GEcurrentDevice(); if(oldd->dev->deactivate) oldd->dev->deactivate(oldd->dev); } /* find empty slot for new descriptor */ i = 1; if (CDR(s) == R_NilValue) appnd = TRUE; else { s = CDR(s); appnd = FALSE; } while (R_Devices[i] != NULL) { i++; if (CDR(s) == R_NilValue) appnd = TRUE; else s = CDR(s); } R_CurrentDevice = i; R_NumDevices++; R_Devices[i] = gdd; active[i] = TRUE; GEregisterWithDevice(gdd); if(gdd->dev->activate) gdd->dev->activate(gdd->dev); /* maintain .Devices (.Device has already been set) */ t = PROTECT(duplicate(getSymbolValue(R_DeviceSymbol))); if (appnd) SETCDR(s, CONS(t, R_NilValue)); else SETCAR(s, t); UNPROTECT(2); /* In case a device driver did not call R_CheckDeviceAvailable before starting its allocation, we complete the allocation and then call killDevice here. This ensures that the device gets a chance to deallocate its resources and the current active device is restored to a sane value. */ if (i == R_MaxDevices - 1) { killDevice(i); error(_("too many open devices")); } }
SEXP devoff(SEXP args) { checkArity_length; killDevice(INTEGER(CAR(args))[0] - 1); return R_NilValue; }