michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- michael@0: * vim: sw=2 ts=8 et : michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include "nsCRTGlue.h" michael@0: #include "prenv.h" michael@0: michael@0: #include "GfxInfoX11.h" michael@0: michael@0: #ifdef MOZ_CRASHREPORTER michael@0: #include "nsExceptionHandler.h" michael@0: #include "nsICrashReporter.h" michael@0: #endif michael@0: michael@0: namespace mozilla { michael@0: namespace widget { michael@0: michael@0: #ifdef DEBUG michael@0: NS_IMPL_ISUPPORTS_INHERITED(GfxInfo, GfxInfoBase, nsIGfxInfoDebug) michael@0: #endif michael@0: michael@0: // these global variables will be set when firing the glxtest process michael@0: int glxtest_pipe = 0; michael@0: pid_t glxtest_pid = 0; michael@0: michael@0: nsresult michael@0: GfxInfo::Init() michael@0: { michael@0: mGLMajorVersion = 0; michael@0: mMajorVersion = 0; michael@0: mMinorVersion = 0; michael@0: mRevisionVersion = 0; michael@0: mIsMesa = false; michael@0: mIsNVIDIA = false; michael@0: mIsFGLRX = false; michael@0: mIsNouveau = false; michael@0: mIsIntel = false; michael@0: mIsOldSwrast = false; michael@0: mIsLlvmpipe = false; michael@0: mHasTextureFromPixmap = false; michael@0: return GfxInfoBase::Init(); michael@0: } michael@0: michael@0: void michael@0: GfxInfo::GetData() michael@0: { michael@0: // to understand this function, see bug 639842. We retrieve the OpenGL driver information in a michael@0: // separate process to protect against bad drivers. michael@0: michael@0: // if glxtest_pipe == 0, that means that we already read the information michael@0: if (!glxtest_pipe) michael@0: return; michael@0: michael@0: enum { buf_size = 1024 }; michael@0: char buf[buf_size]; michael@0: ssize_t bytesread = read(glxtest_pipe, michael@0: &buf, michael@0: buf_size-1); // -1 because we'll append a zero michael@0: close(glxtest_pipe); michael@0: glxtest_pipe = 0; michael@0: michael@0: // bytesread < 0 would mean that the above read() call failed. michael@0: // This should never happen. If it did, the outcome would be to blacklist anyway. michael@0: if (bytesread < 0) michael@0: bytesread = 0; michael@0: michael@0: // let buf be a zero-terminated string michael@0: buf[bytesread] = 0; michael@0: michael@0: // Wait for the glxtest process to finish. This serves 2 purposes: michael@0: // * avoid having a zombie glxtest process laying around michael@0: // * get the glxtest process status info. michael@0: int glxtest_status = 0; michael@0: bool wait_for_glxtest_process = true; michael@0: bool waiting_for_glxtest_process_failed = false; michael@0: int waitpid_errno = 0; michael@0: while(wait_for_glxtest_process) { michael@0: wait_for_glxtest_process = false; michael@0: if (waitpid(glxtest_pid, &glxtest_status, 0) == -1) { michael@0: waitpid_errno = errno; michael@0: if (waitpid_errno == EINTR) { michael@0: wait_for_glxtest_process = true; michael@0: } else { michael@0: // Bug 718629 michael@0: // ECHILD happens when the glxtest process got reaped got reaped after a PR_CreateProcess michael@0: // as per bug 227246. This shouldn't matter, as we still seem to get the data michael@0: // from the pipe, and if we didn't, the outcome would be to blacklist anyway. michael@0: waiting_for_glxtest_process_failed = (waitpid_errno != ECHILD); michael@0: } michael@0: } michael@0: } michael@0: michael@0: bool exited_with_error_code = !waiting_for_glxtest_process_failed && michael@0: WIFEXITED(glxtest_status) && michael@0: WEXITSTATUS(glxtest_status) != EXIT_SUCCESS; michael@0: bool received_signal = !waiting_for_glxtest_process_failed && michael@0: WIFSIGNALED(glxtest_status); michael@0: michael@0: bool error = waiting_for_glxtest_process_failed || exited_with_error_code || received_signal; michael@0: michael@0: nsCString textureFromPixmap; michael@0: nsCString *stringToFill = nullptr; michael@0: char *bufptr = buf; michael@0: if (!error) { michael@0: while(true) { michael@0: char *line = NS_strtok("\n", &bufptr); michael@0: if (!line) michael@0: break; michael@0: if (stringToFill) { michael@0: stringToFill->Assign(line); michael@0: stringToFill = nullptr; michael@0: } michael@0: else if(!strcmp(line, "VENDOR")) michael@0: stringToFill = &mVendor; michael@0: else if(!strcmp(line, "RENDERER")) michael@0: stringToFill = &mRenderer; michael@0: else if(!strcmp(line, "VERSION")) michael@0: stringToFill = &mVersion; michael@0: else if(!strcmp(line, "TFP")) michael@0: stringToFill = &textureFromPixmap; michael@0: } michael@0: } michael@0: michael@0: if (!strcmp(textureFromPixmap.get(), "TRUE")) michael@0: mHasTextureFromPixmap = true; michael@0: michael@0: // only useful for Linux kernel version check for FGLRX driver. michael@0: // assumes X client == X server, which is sad. michael@0: struct utsname unameobj; michael@0: if (!uname(&unameobj)) michael@0: { michael@0: mOS.Assign(unameobj.sysname); michael@0: mOSRelease.Assign(unameobj.release); michael@0: } michael@0: michael@0: const char *spoofedVendor = PR_GetEnv("MOZ_GFX_SPOOF_GL_VENDOR"); michael@0: if (spoofedVendor) michael@0: mVendor.Assign(spoofedVendor); michael@0: const char *spoofedRenderer = PR_GetEnv("MOZ_GFX_SPOOF_GL_RENDERER"); michael@0: if (spoofedRenderer) michael@0: mRenderer.Assign(spoofedRenderer); michael@0: const char *spoofedVersion = PR_GetEnv("MOZ_GFX_SPOOF_GL_VERSION"); michael@0: if (spoofedVersion) michael@0: mVersion.Assign(spoofedVersion); michael@0: const char *spoofedOS = PR_GetEnv("MOZ_GFX_SPOOF_OS"); michael@0: if (spoofedOS) michael@0: mOS.Assign(spoofedOS); michael@0: const char *spoofedOSRelease = PR_GetEnv("MOZ_GFX_SPOOF_OS_RELEASE"); michael@0: if (spoofedOSRelease) michael@0: mOSRelease.Assign(spoofedOSRelease); michael@0: michael@0: if (error || michael@0: mVendor.IsEmpty() || michael@0: mRenderer.IsEmpty() || michael@0: mVersion.IsEmpty() || michael@0: mOS.IsEmpty() || michael@0: mOSRelease.IsEmpty()) michael@0: { michael@0: mAdapterDescription.AppendLiteral("GLXtest process failed"); michael@0: if (waiting_for_glxtest_process_failed) michael@0: mAdapterDescription.AppendPrintf(" (waitpid failed with errno=%d for pid %d)", waitpid_errno, glxtest_pid); michael@0: if (exited_with_error_code) michael@0: mAdapterDescription.AppendPrintf(" (exited with status %d)", WEXITSTATUS(glxtest_status)); michael@0: if (received_signal) michael@0: mAdapterDescription.AppendPrintf(" (received signal %d)", WTERMSIG(glxtest_status)); michael@0: if (bytesread) { michael@0: mAdapterDescription.AppendLiteral(": "); michael@0: mAdapterDescription.Append(nsDependentCString(buf)); michael@0: mAdapterDescription.AppendLiteral("\n"); michael@0: } michael@0: #ifdef MOZ_CRASHREPORTER michael@0: CrashReporter::AppendAppNotesToCrashReport(mAdapterDescription); michael@0: #endif michael@0: return; michael@0: } michael@0: michael@0: mAdapterDescription.Append(mVendor); michael@0: mAdapterDescription.AppendLiteral(" -- "); michael@0: mAdapterDescription.Append(mRenderer); michael@0: michael@0: nsAutoCString note; michael@0: note.Append("OpenGL: "); michael@0: note.Append(mAdapterDescription); michael@0: note.Append(" -- "); michael@0: note.Append(mVersion); michael@0: if (mHasTextureFromPixmap) michael@0: note.Append(" -- texture_from_pixmap"); michael@0: note.Append("\n"); michael@0: #ifdef MOZ_CRASHREPORTER michael@0: CrashReporter::AppendAppNotesToCrashReport(note); michael@0: #endif michael@0: michael@0: // determine the major OpenGL version. That's the first integer in the version string. michael@0: mGLMajorVersion = strtol(mVersion.get(), 0, 10); michael@0: michael@0: // determine driver type (vendor) and where in the version string michael@0: // the actual driver version numbers should be expected to be found (whereToReadVersionNumbers) michael@0: const char *whereToReadVersionNumbers = nullptr; michael@0: const char *Mesa_in_version_string = strstr(mVersion.get(), "Mesa"); michael@0: if (Mesa_in_version_string) { michael@0: mIsMesa = true; michael@0: // with Mesa, the version string contains "Mesa major.minor" and that's all the version information we get: michael@0: // there is no actual driver version info. michael@0: whereToReadVersionNumbers = Mesa_in_version_string + strlen("Mesa"); michael@0: if (strcasestr(mVendor.get(), "nouveau")) michael@0: mIsNouveau = true; michael@0: if (strcasestr(mRenderer.get(), "intel")) // yes, intel is in the renderer string michael@0: mIsIntel = true; michael@0: if (strcasestr(mRenderer.get(), "llvmpipe")) michael@0: mIsLlvmpipe = true; michael@0: if (strcasestr(mRenderer.get(), "software rasterizer")) michael@0: mIsOldSwrast = true; michael@0: } else if (strstr(mVendor.get(), "NVIDIA Corporation")) { michael@0: mIsNVIDIA = true; michael@0: // with the NVIDIA driver, the version string contains "NVIDIA major.minor" michael@0: // note that here the vendor and version strings behave differently, that's why we don't put this above michael@0: // alongside Mesa_in_version_string. michael@0: const char *NVIDIA_in_version_string = strstr(mVersion.get(), "NVIDIA"); michael@0: if (NVIDIA_in_version_string) michael@0: whereToReadVersionNumbers = NVIDIA_in_version_string + strlen("NVIDIA"); michael@0: } else if (strstr(mVendor.get(), "ATI Technologies Inc")) { michael@0: mIsFGLRX = true; michael@0: // with the FGLRX driver, the version string only gives a OpenGL version :/ so let's return that. michael@0: // that can at least give a rough idea of how old the driver is. michael@0: whereToReadVersionNumbers = mVersion.get(); michael@0: } michael@0: michael@0: // read major.minor version numbers of the driver (not to be confused with the OpenGL version) michael@0: if (whereToReadVersionNumbers) { michael@0: // copy into writable buffer, for tokenization michael@0: strncpy(buf, whereToReadVersionNumbers, buf_size); michael@0: bufptr = buf; michael@0: michael@0: // now try to read major.minor version numbers. In case of failure, gracefully exit: these numbers have michael@0: // been initialized as 0 anyways michael@0: char *token = NS_strtok(".", &bufptr); michael@0: if (token) { michael@0: mMajorVersion = strtol(token, 0, 10); michael@0: token = NS_strtok(".", &bufptr); michael@0: if (token) { michael@0: mMinorVersion = strtol(token, 0, 10); michael@0: token = NS_strtok(".", &bufptr); michael@0: if (token) michael@0: mRevisionVersion = strtol(token, 0, 10); michael@0: } michael@0: } michael@0: } michael@0: } michael@0: michael@0: static inline uint64_t version(uint32_t major, uint32_t minor, uint32_t revision = 0) michael@0: { michael@0: return (uint64_t(major) << 32) + (uint64_t(minor) << 16) + uint64_t(revision); michael@0: } michael@0: michael@0: const nsTArray& michael@0: GfxInfo::GetGfxDriverInfo() michael@0: { michael@0: // Nothing here yet. michael@0: //if (!mDriverInfo->Length()) { michael@0: // michael@0: //} michael@0: return *mDriverInfo; michael@0: } michael@0: michael@0: nsresult michael@0: GfxInfo::GetFeatureStatusImpl(int32_t aFeature, michael@0: int32_t *aStatus, michael@0: nsAString & aSuggestedDriverVersion, michael@0: const nsTArray& aDriverInfo, michael@0: OperatingSystem* aOS /* = nullptr */) michael@0: michael@0: { michael@0: GetData(); michael@0: michael@0: NS_ENSURE_ARG_POINTER(aStatus); michael@0: *aStatus = nsIGfxInfo::FEATURE_STATUS_UNKNOWN; michael@0: aSuggestedDriverVersion.SetIsVoid(true); michael@0: OperatingSystem os = DRIVER_OS_LINUX; michael@0: if (aOS) michael@0: *aOS = os; michael@0: michael@0: if (mGLMajorVersion == 1) { michael@0: // We're on OpenGL 1. In most cases that indicates really old hardware. michael@0: // We better block them, rather than rely on them to fail gracefully, because they don't! michael@0: // see bug 696636 michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: return NS_OK; michael@0: } michael@0: michael@0: // Don't evaluate any special cases if we're checking the downloaded blocklist. michael@0: if (!aDriverInfo.Length()) { michael@0: // Only check features relevant to Linux. michael@0: if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS || michael@0: aFeature == nsIGfxInfo::FEATURE_WEBGL_OPENGL || michael@0: aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) { michael@0: michael@0: // Disable OpenGL layers when we don't have texture_from_pixmap because it regresses performance. michael@0: if (aFeature == nsIGfxInfo::FEATURE_OPENGL_LAYERS && !mHasTextureFromPixmap) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: aSuggestedDriverVersion.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: // whitelist the linux test slaves' current configuration. michael@0: // this is necessary as they're still using the slightly outdated 190.42 driver. michael@0: // this isn't a huge risk, as at least this is the exact setting in which we do continuous testing, michael@0: // and this only affects GeForce 9400 cards on linux on this precise driver version, which is very few users. michael@0: // We do the same thing on Windows XP, see in widget/windows/GfxInfo.cpp michael@0: if (mIsNVIDIA && michael@0: !strcmp(mRenderer.get(), "GeForce 9400/PCI/SSE2") && michael@0: !strcmp(mVersion.get(), "3.2.0 NVIDIA 190.42")) michael@0: { michael@0: *aStatus = nsIGfxInfo::FEATURE_NO_INFO; michael@0: return NS_OK; michael@0: } michael@0: michael@0: if (mIsMesa) { michael@0: if (mIsNouveau && version(mMajorVersion, mMinorVersion) < version(8,0)) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: aSuggestedDriverVersion.AssignLiteral("Mesa 8.0"); michael@0: } michael@0: else if (version(mMajorVersion, mMinorVersion, mRevisionVersion) < version(7,10,3)) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: aSuggestedDriverVersion.AssignLiteral("Mesa 7.10.3"); michael@0: } michael@0: else if (mIsOldSwrast) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: } michael@0: else if (mIsLlvmpipe && version(mMajorVersion, mMinorVersion) < version(9, 1)) { michael@0: // bug 791905, Mesa bug 57733, fixed in Mesa 9.1 according to michael@0: // https://bugs.freedesktop.org/show_bug.cgi?id=57733#c3 michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: } michael@0: else if (aFeature == nsIGfxInfo::FEATURE_WEBGL_MSAA) michael@0: { michael@0: if (mIsIntel && version(mMajorVersion, mMinorVersion) < version(8,1)) michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: aSuggestedDriverVersion.AssignLiteral("Mesa 8.1"); michael@0: } michael@0: michael@0: } else if (mIsNVIDIA) { michael@0: if (version(mMajorVersion, mMinorVersion, mRevisionVersion) < version(257,21)) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: aSuggestedDriverVersion.AssignLiteral("NVIDIA 257.21"); michael@0: } michael@0: } else if (mIsFGLRX) { michael@0: // FGLRX does not report a driver version number, so we have the OpenGL version instead. michael@0: // by requiring OpenGL 3, we effectively require recent drivers. michael@0: if (version(mMajorVersion, mMinorVersion, mRevisionVersion) < version(3, 0)) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DRIVER_VERSION; michael@0: aSuggestedDriverVersion.AssignLiteral(""); michael@0: } michael@0: // Bug 724640: FGLRX + Linux 2.6.32 is a crashy combo michael@0: bool unknownOS = mOS.IsEmpty() || mOSRelease.IsEmpty(); michael@0: bool badOS = mOS.Find("Linux", true) != -1 && michael@0: mOSRelease.Find("2.6.32") != -1; michael@0: if (unknownOS || badOS) { michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_OS_VERSION; michael@0: } michael@0: } else { michael@0: // like on windows, let's block unknown vendors. Think of virtual machines. michael@0: // Also, this case is hit whenever the GLXtest probe failed to get driver info or crashed. michael@0: *aStatus = nsIGfxInfo::FEATURE_BLOCKED_DEVICE; michael@0: } michael@0: } michael@0: } michael@0: michael@0: return GfxInfoBase::GetFeatureStatusImpl(aFeature, aStatus, aSuggestedDriverVersion, aDriverInfo, &os); michael@0: } michael@0: michael@0: michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetD2DEnabled(bool *aEnabled) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetDWriteEnabled(bool *aEnabled) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString DWriteVersion; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetDWriteVersion(nsAString & aDwriteVersion) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString cleartypeParameters; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetCleartypeParameters(nsAString & aCleartypeParams) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDescription; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDescription(nsAString & aAdapterDescription) michael@0: { michael@0: GetData(); michael@0: AppendASCIItoUTF16(mAdapterDescription, aAdapterDescription); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDescription2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDescription2(nsAString & aAdapterDescription) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterRAM; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterRAM(nsAString & aAdapterRAM) michael@0: { michael@0: aAdapterRAM.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterRAM2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterRAM2(nsAString & aAdapterRAM) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriver; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriver(nsAString & aAdapterDriver) michael@0: { michael@0: aAdapterDriver.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriver2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriver2(nsAString & aAdapterDriver) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverVersion; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverVersion(nsAString & aAdapterDriverVersion) michael@0: { michael@0: GetData(); michael@0: CopyASCIItoUTF16(mVersion, aAdapterDriverVersion); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverVersion2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverVersion2(nsAString & aAdapterDriverVersion) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverDate; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverDate(nsAString & aAdapterDriverDate) michael@0: { michael@0: aAdapterDriverDate.AssignLiteral(""); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDriverDate2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDriverDate2(nsAString & aAdapterDriverDate) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterVendorID; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterVendorID(nsAString & aAdapterVendorID) michael@0: { michael@0: GetData(); michael@0: CopyUTF8toUTF16(mVendor, aAdapterVendorID); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterVendorID2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterVendorID2(nsAString & aAdapterVendorID) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDeviceID; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDeviceID(nsAString & aAdapterDeviceID) michael@0: { michael@0: GetData(); michael@0: CopyUTF8toUTF16(mRenderer, aAdapterDeviceID); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* readonly attribute DOMString adapterDeviceID2; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetAdapterDeviceID2(nsAString & aAdapterDeviceID) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: /* readonly attribute boolean isGPU2Active; */ michael@0: NS_IMETHODIMP michael@0: GfxInfo::GetIsGPU2Active(bool* aIsGPU2Active) michael@0: { michael@0: return NS_ERROR_FAILURE; michael@0: } michael@0: michael@0: #ifdef DEBUG michael@0: michael@0: // Implement nsIGfxInfoDebug michael@0: // We don't support spoofing anything on Linux michael@0: michael@0: /* void spoofVendorID (in DOMString aVendorID); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofVendorID(const nsAString & aVendorID) michael@0: { michael@0: CopyUTF16toUTF8(aVendorID, mVendor); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void spoofDeviceID (in unsigned long aDeviceID); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofDeviceID(const nsAString & aDeviceID) michael@0: { michael@0: CopyUTF16toUTF8(aDeviceID, mRenderer); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void spoofDriverVersion (in DOMString aDriverVersion); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofDriverVersion(const nsAString & aDriverVersion) michael@0: { michael@0: CopyUTF16toUTF8(aDriverVersion, mVersion); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void spoofOSVersion (in unsigned long aVersion); */ michael@0: NS_IMETHODIMP GfxInfo::SpoofOSVersion(uint32_t aVersion) michael@0: { michael@0: // We don't support OS versioning on Linux. There's just "Linux". michael@0: return NS_OK; michael@0: } michael@0: michael@0: #endif michael@0: michael@0: } // end namespace widget michael@0: } // end namespace mozilla