/**
 * Loads the plugin into memory using NSPR's shared-library loading
 * mechanism. Handles platform differences in loading shared libraries.
 */
nsresult nsPluginFile::LoadPlugin(PRLibrary **outLibrary)
{
        nsCAutoString path;
        nsresult rv = mPlugin->GetNativePath(path);
        if (NS_OK != rv) {
            return rv;
        }
        pLibrary = *outLibrary = PR_LoadLibrary(path.get());

#ifdef NS_DEBUG
        printf("LoadPlugin() %s returned %lx\n",path,(unsigned long)pLibrary);
#endif

        return NS_OK;
}
MediaPluginHost::MediaPluginHost() {
  MOZ_COUNT_CTOR(MediaPluginHost);

  const char* name = GetOmxLibraryName();
  ALOG("Loading OMX Plugin: %s", name ? name : "nullptr");
  if (name) {
    PRLibrary *lib = PR_LoadLibrary(name);
    if (lib) {
      Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
      if (manifest) {
        mPlugins.AppendElement(manifest);
        ALOG("OMX plugin successfully loaded");
     }
    }
  }
}
/*
 * load the smime library and look up the SEC_ReadPKCS7Certs function.
 *  we do this so we don't have a circular depenency on the smime library,
 *  and also so we don't have to load the smime library in applications that
 * don't use it.
 */
static PRStatus PR_CALLBACK pkix_getDecodeFunction(void)
{
    pkix_decodeFunc.smimeLib = 
		PR_LoadLibrary(SHLIB_PREFIX"smime3."SHLIB_SUFFIX);
    if (pkix_decodeFunc.smimeLib == NULL) {
	return PR_FAILURE;
    }

    pkix_decodeFunc.func = (pkix_DecodeCertsFunc) PR_FindFunctionSymbol(
		pkix_decodeFunc.smimeLib, "CERT_DecodeCertPackage");
    if (!pkix_decodeFunc.func) {
	return PR_FAILURE;
    }
    return PR_SUCCESS;

}
Beispiel #4
0
DB *
rdbopen(const char *appName, const char *prefix,
        const char *type, int flags, int *status)
{
    PRLibrary *lib;
    DB *db;
    char *disableUnload = NULL;

    if (lg_rdbfunc) {
        db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
        if (!db && status && lg_rdbstatusfunc) {
            *status = (*lg_rdbstatusfunc)();
        }
        return db;
    }

    /*
     * try to open the library.
     */
    lib = PR_LoadLibrary(RDBLIB);

    if (!lib) {
        return NULL;
    }

    /* get the entry points */
    lg_rdbstatusfunc = (rdbstatusfunc)PR_FindSymbol(lib, "rdbstatus");
    lg_rdbfunc = (rdbfunc)PR_FindSymbol(lib, "rdbopen");
    if (lg_rdbfunc) {
        db = (*lg_rdbfunc)(appName, prefix, type, rdbmapflags(flags));
        if (!db && status && lg_rdbstatusfunc) {
            *status = (*lg_rdbstatusfunc)();
        }
        return db;
    }

    /* couldn't find the entry point, unload the library and fail */
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (!disableUnload) {
        PR_UnloadLibrary(lib);
    }
    return NULL;
}
static void Initialize()
{
    sInitialized = true;

#if !defined(MOZ_PLATFORM_MAEMO) && defined(MOZ_X11)
    // This will leak - See comments in ~nsIdleServiceQt().
    PRLibrary* xsslib = PR_LoadLibrary("libXss.so.1");
    if (!xsslib) {
        return;
    }

    _XSSQueryExtension = (_XScreenSaverQueryExtension_fn)
        PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryExtension");
    _XSSAllocInfo = (_XScreenSaverAllocInfo_fn)
        PR_FindFunctionSymbol(xsslib, "XScreenSaverAllocInfo");
    _XSSQueryInfo = (_XScreenSaverQueryInfo_fn)
        PR_FindFunctionSymbol(xsslib, "XScreenSaverQueryInfo");
#endif
}
Beispiel #6
0
Module::Module (std::string name, std::string path)
{
    if (name.empty()) {
        throw std::runtime_error("What module should I load?");
    }

    if (path.empty()) {
        path.assign("modules/");
    }

    _path = path;
    _name = name;

    _library = PR_LoadLibrary(PR_GetLibraryName(_path.c_str(), _name.c_str()));

    if (_library == NULL) {
        throw std::runtime_error("Module " + _name + " not found.");
    }
}
Beispiel #7
0
static PRLibrary* LoadApitraceLibrary()
{
    static bool sUseApitraceInitialized = false;
    static bool sUseApitrace = false;

    if (!sUseApitraceInitialized) {
        sUseApitrace = Preferences::GetBool("gfx.apitrace.enabled", false);
        sUseApitraceInitialized = true;
    }

    if (!sUseApitrace) {
        return nullptr;
    }

    static PRLibrary* sApitraceLibrary = NULL;

    if (sApitraceLibrary)
        return sApitraceLibrary;

    nsCString logFile = Preferences::GetCString("gfx.apitrace.logfile");

    if (logFile.IsEmpty()) {
        logFile = "firefox.trace";
    }

    // The firefox process can't write to /data/local, but it can write
    // to $GRE_HOME/
    nsAutoCString logPath;
    logPath.AppendPrintf("%s/%s", getenv("GRE_HOME"), logFile.get());

    // apitrace uses the TRACE_FILE environment variable to determine where
    // to log trace output to
    printf_stderr("Logging GL tracing output to %s", logPath.get());
    setenv("TRACE_FILE", logPath.get(), false);

    printf_stderr("Attempting load of %s\n", APITRACE_LIB);

    sApitraceLibrary = PR_LoadLibrary(APITRACE_LIB);

    return sApitraceLibrary;
}
static nsresult
ensure_libgnome()
{
    if (!gTriedToLoadGnomeLibs) {
        gLibGnome = PR_LoadLibrary("libgnome-2.so.0");
        if (!gLibGnome)
            return NS_ERROR_NOT_AVAILABLE;

        _gnome_program_get = (_GnomeProgramGet_fn)PR_FindFunctionSymbol(gLibGnome, "gnome_program_get");
        if (!_gnome_program_get) {
            PR_UnloadLibrary(gLibGnome);
            gLibGnome = nullptr;
            return NS_ERROR_NOT_AVAILABLE;
        }
    }

    if (!gLibGnome)
        return NS_ERROR_NOT_AVAILABLE;

    return NS_OK;
}
/**
 * Loads the plugin into memory using NSPR's shared-library loading
 * mechanism. Handles platform differences in loading shared libraries.
 */
nsresult nsPluginFile::LoadPlugin(PRLibrary* &outLibrary)
{
  const char* path;

  if (!mPlugin)
    return NS_ERROR_NULL_POINTER;

  nsCAutoString temp;
  mPlugin->GetNativePath(temp);
  path = temp.get();

  outLibrary = PR_LoadLibrary(path);
  pLibrary = outLibrary;
  if (!outLibrary) {
    return NS_ERROR_FAILURE;
  }
#ifdef DEBUG
  printf("[loaded plugin %s]\n", path);
#endif
  return NS_OK;
}
static nsresult
ensure_libgnomevfs()
{
    if (!gTriedToLoadGnomeLibs) {
        gLibGnomeVFS = PR_LoadLibrary("libgnomevfs-2.so.0");
        if (!gLibGnomeVFS)
            return NS_ERROR_NOT_AVAILABLE;

        _gnome_vfs_get_file_info = (_GnomeVFSGetFileInfo_fn)PR_FindFunctionSymbol(gLibGnomeVFS, "gnome_vfs_get_file_info");
        _gnome_vfs_file_info_clear = (_GnomeVFSFileInfoClear_fn)PR_FindFunctionSymbol(gLibGnomeVFS, "gnome_vfs_file_info_clear");
        if (!_gnome_vfs_get_file_info || !_gnome_vfs_file_info_clear) {
            PR_UnloadLibrary(gLibGnomeVFS);
            gLibGnomeVFS = nullptr;
            return NS_ERROR_NOT_AVAILABLE;
        }
    }

    if (!gLibGnomeVFS)
        return NS_ERROR_NOT_AVAILABLE;

    return NS_OK;
}
void MediaPluginHost::TryLoad(const char *name)
{
  bool forceEnabled =
      Preferences::GetBool("stagefright.force-enabled", false);
  bool disabled =
      Preferences::GetBool("stagefright.disabled", false);

  if (disabled) {
    NS_WARNING("XXX stagefright disabled\n");
    return;
  }

  ScopedGfxFeatureReporter reporter("Stagefright", forceEnabled);

  if (!forceEnabled) {
    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
    if (gfxInfo) {
      int32_t status;
      if (NS_SUCCEEDED(gfxInfo->GetFeatureStatus(nsIGfxInfo::FEATURE_STAGEFRIGHT, &status))) {
        if (status != nsIGfxInfo::FEATURE_NO_INFO) {
          NS_WARNING("XXX stagefright blacklisted\n");
          return;
        }
      }
    }
  }

  reporter.SetSuccessful();

  PRLibrary *lib = PR_LoadLibrary(name);
  if (lib) {
    Manifest *manifest = static_cast<Manifest *>(PR_FindSymbol(lib, "MPAPI_MANIFEST"));
    if (manifest)
      mPlugins.AppendElement(manifest);
  }
}
NS_IMETHODIMP
nsNativeAppSupportUnix::Start(bool *aRetVal)
{
  NS_ASSERTION(gAppData, "gAppData must not be null.");

// The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService,
// from diffrent threads. This could lead to race conditions if the dbus is not
// initialized before making any other library calls.
#ifdef MOZ_ENABLE_DBUS
  dbus_threads_init_default();
#endif

#if (MOZ_WIDGET_GTK == 2)
  if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
      (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
    GtkWidget* versionErrDialog = gtk_message_dialog_new(nullptr,
                     GtkDialogFlags(GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT),
                     GTK_MESSAGE_ERROR,
                     GTK_BUTTONS_OK,
                     UNSUPPORTED_GTK_MSG,
                     gtk_major_version,
                     gtk_minor_version,
                     MIN_GTK_MAJOR_VERSION,
                     MIN_GTK_MINOR_VERSION);
    gtk_dialog_run(GTK_DIALOG(versionErrDialog));
    gtk_widget_destroy(versionErrDialog);
    exit(0);
  }
#endif

  *aRetVal = true;

#ifdef MOZ_X11
  gboolean sm_disable = FALSE;
  if (!getenv("SESSION_MANAGER")) {
    sm_disable = TRUE;
  }

  nsAutoCString prev_client_id;

  char **curarg = gArgv + 1;
  while (*curarg) {
    char *arg = *curarg;
    if (arg[0] == '-' && arg[1] == '-') {
      arg += 2;
      if (!strcmp(arg, "sm-disable")) {
        RemoveArg(curarg);
        sm_disable = TRUE;
        continue;
      } else if (!strcmp(arg, "sm-client-id")) {
        RemoveArg(curarg);
        if (*curarg[0] != '-') {
          prev_client_id = *curarg;
          RemoveArg(curarg);
        }
        continue;
      }
    }

    ++curarg;
  }

  if (prev_client_id.IsEmpty()) {
    prev_client_id = getenv("DESKTOP_AUTOSTART_ID");
  }

  // We don't want child processes to use the same ID
  unsetenv("DESKTOP_AUTOSTART_ID");

  char *client_id = nullptr;
  if (!sm_disable) {
    PRLibrary *iceLib = PR_LoadLibrary("libICE.so.6");
    if (!iceLib) {
      return NS_OK;
    }

    PRLibrary *smLib = PR_LoadLibrary("libSM.so.6");
    if (!smLib) {
      PR_UnloadLibrary(iceLib);
      return NS_OK;
    }

    IceSetIOErrorHandler = (IceSetIOErrorHandlerFn)PR_FindFunctionSymbol(iceLib, "IceSetIOErrorHandler");
    IceAddConnectionWatch = (IceAddConnectionWatchFn)PR_FindFunctionSymbol(iceLib, "IceAddConnectionWatch");
    IceConnectionNumber = (IceConnectionNumberFn)PR_FindFunctionSymbol(iceLib, "IceConnectionNumber");
    IceProcessMessages = (IceProcessMessagesFn)PR_FindFunctionSymbol(iceLib, "IceProcessMessages");
    IceGetConnectionContext = (IceGetConnectionContextFn)PR_FindFunctionSymbol(iceLib, "IceGetConnectionContext");
    if (!IceSetIOErrorHandler || !IceAddConnectionWatch ||
	!IceConnectionNumber  || !IceProcessMessages || !IceGetConnectionContext) {
      PR_UnloadLibrary(iceLib);
      PR_UnloadLibrary(smLib);
      return NS_OK;
    }

    SmcInteractDone = (SmcInteractDoneFn)PR_FindFunctionSymbol(smLib, "SmcInteractDone");
    SmcSaveYourselfDone = (SmcSaveYourselfDoneFn)PR_FindFunctionSymbol(smLib, "SmcSaveYourselfDone");
    SmcInteractRequest = (SmcInteractRequestFn)PR_FindFunctionSymbol(smLib, "SmcInteractRequest");
    SmcCloseConnection = (SmcCloseConnectionFn)PR_FindFunctionSymbol(smLib, "SmcCloseConnection");
    SmcOpenConnection = (SmcOpenConnectionFn)PR_FindFunctionSymbol(smLib, "SmcOpenConnection");
    SmcSetProperties = (SmcSetPropertiesFn)PR_FindFunctionSymbol(smLib, "SmcSetProperties");
    if (!SmcInteractDone || !SmcSaveYourselfDone || !SmcInteractRequest ||
        !SmcCloseConnection || !SmcOpenConnection || !SmcSetProperties) {
      PR_UnloadLibrary(iceLib);
      PR_UnloadLibrary(smLib);
      return NS_OK;
    }

    ice_init();

    // all callbacks are mandatory in libSM 1.0, so listen even if we don't care.
    unsigned long mask = SmcSaveYourselfProcMask | SmcDieProcMask |
                         SmcSaveCompleteProcMask | SmcShutdownCancelledProcMask;

    SmcCallbacks callbacks;
    callbacks.save_yourself.callback = nsNativeAppSupportUnix::SaveYourselfCB;
    callbacks.save_yourself.client_data = static_cast<SmPointer>(this);

    callbacks.die.callback = nsNativeAppSupportUnix::DieCB;
    callbacks.die.client_data = static_cast<SmPointer>(this);

    callbacks.save_complete.callback = nsNativeAppSupportUnix::SaveCompleteCB;
    callbacks.save_complete.client_data = nullptr;

    callbacks.shutdown_cancelled.callback =
      nsNativeAppSupportUnix::ShutdownCancelledCB;
    callbacks.shutdown_cancelled.client_data = static_cast<SmPointer>(this);

    char errbuf[256];
    mSessionConnection = SmcOpenConnection(nullptr, this, SmProtoMajor,
                                           SmProtoMinor, mask, &callbacks,
                                           prev_client_id.get(), &client_id,
                                           sizeof(errbuf), errbuf);
  }

  if (!mSessionConnection) {
    return NS_OK;
  }

  LogModule::Init();  // need to make sure initialized before SetClientState
  if (prev_client_id.IsEmpty() ||
      (client_id && !prev_client_id.Equals(client_id))) {
    SetClientState(STATE_REGISTERING);
  } else {
    SetClientState(STATE_IDLE);
  }

  gdk_x11_set_sm_client_id(client_id);

  // Set SM Properties
  // SmCloneCommand, SmProgram, SmRestartCommand, SmUserID are required
  // properties so must be set, and must have a sensible fallback value.

  // Determine executable path to use for XSMP session restore

  // Is there a request to suppress default binary launcher?
  nsAutoCString path(getenv("MOZ_APP_LAUNCHER"));

  if (path.IsEmpty()) {
    NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
    nsCOMPtr<nsIFile> executablePath;
    nsresult rv;

    bool dummy;
    rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));

    if (NS_SUCCEEDED(rv)) {
      // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
      nsAutoCString leafName;
      rv = executablePath->GetNativeLeafName(leafName);
      if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
        leafName.SetLength(leafName.Length() - strlen("-bin"));
        executablePath->SetNativeLeafName(leafName);
      }

      executablePath->GetNativePath(path);
    }
  }

  if (path.IsEmpty()) {
    // can't determine executable path. Best fallback is name from
    // application.ini but it might not resolve to the same executable at
    // launch time.
    path = gAppData->name;  // will always be set
    ToLowerCase(path);
    MOZ_LOG(sMozSMLog, LogLevel::Warning,
        ("Could not determine executable path. Falling back to %s.", path.get()));
  }

  SmProp propRestart, propClone, propProgram, propUser, *props[4];
  SmPropValue valsRestart[3], valsClone[1], valsProgram[1], valsUser[1];
  int n = 0;

  NS_NAMED_LITERAL_CSTRING(kClientIDParam, "--sm-client-id");

  SetSMValue(valsRestart[0], path);
  SetSMValue(valsRestart[1], kClientIDParam);
  SetSMValue(valsRestart[2], nsDependentCString(client_id));
  SetSMProperty(propRestart, SmRestartCommand, SmLISTofARRAY8, 3, valsRestart);
  props[n++] = &propRestart;

  SetSMValue(valsClone[0], path);
  SetSMProperty(propClone, SmCloneCommand, SmLISTofARRAY8, 1, valsClone);
  props[n++] = &propClone;

  nsAutoCString appName(gAppData->name);  // will always be set
  ToLowerCase(appName);

  SetSMValue(valsProgram[0], appName);
  SetSMProperty(propProgram, SmProgram, SmARRAY8, 1, valsProgram);
  props[n++] = &propProgram;

  nsAutoCString userName;  // username that started the program
  struct passwd* pw = getpwuid(getuid());
  if (pw && pw->pw_name) {
    userName = pw->pw_name;
  } else {
    userName = NS_LITERAL_CSTRING("nobody");
    MOZ_LOG(sMozSMLog, LogLevel::Warning,
        ("Could not determine user-name. Falling back to %s.", userName.get()));
  }

  SetSMValue(valsUser[0], userName);
  SetSMProperty(propUser, SmUserID, SmARRAY8, 1, valsUser);
  props[n++] = &propUser;

  SmcSetProperties(mSessionConnection, n, props);

  g_free(client_id);
#endif /* MOZ_X11 */

  return NS_OK;
}
bool
GLXLibrary::EnsureInitialized(LibType libType)
{
    if (mInitialized) {
        return true;
    }

    // Don't repeatedly try to initialize.
    if (mTriedInitializing) {
        return false;
    }
    mTriedInitializing = true;

    // Force enabling s3 texture compression. (Bug 774134)
    PR_SetEnv("force_s3tc_enable=true");

    if (!mOGLLibrary) {
        const char* libGLfilename = nullptr;
        bool forceFeatureReport = false;
        switch (libType) {
        case MESA_LLVMPIPE_LIB:
            libGLfilename = "mesallvmpipe.so";
            forceFeatureReport = true;
            break;
        case OPENGL_LIB:
            // see e.g. bug 608526: it is intrinsically interesting to know whether we have dynamically linked to libGL.so.1
            // because at least the NVIDIA implementation requires an executable stack, which causes mprotect calls,
            // which trigger glibc bug http://sourceware.org/bugzilla/show_bug.cgi?id=12225
#ifdef __OpenBSD__
            libGLfilename = "libGL.so";
#else
            libGLfilename = "libGL.so.1";
#endif
            break;
        default:
            MOZ_CRASH("Invalid GLX library type.");
        }

        ScopedGfxFeatureReporter reporter(libGLfilename, forceFeatureReport);
        mOGLLibrary = PR_LoadLibrary(libGLfilename);
        if (!mOGLLibrary) {
            NS_WARNING("Couldn't load OpenGL shared library.");
            return false;
        }
        reporter.SetSuccessful();
    }

    if (PR_GetEnv("MOZ_GLX_DEBUG")) {
        mDebug = true;
    }

    GLLibraryLoader::SymLoadStruct symbols[] = {
        /* functions that were in GLX 1.0 */
        { (PRFuncPtr*) &xDestroyContextInternal, { "glXDestroyContext", nullptr } },
        { (PRFuncPtr*) &xMakeCurrentInternal, { "glXMakeCurrent", nullptr } },
        { (PRFuncPtr*) &xSwapBuffersInternal, { "glXSwapBuffers", nullptr } },
        { (PRFuncPtr*) &xQueryVersionInternal, { "glXQueryVersion", nullptr } },
        { (PRFuncPtr*) &xGetCurrentContextInternal, { "glXGetCurrentContext", nullptr } },
        { (PRFuncPtr*) &xWaitGLInternal, { "glXWaitGL", nullptr } },
        { (PRFuncPtr*) &xWaitXInternal, { "glXWaitX", nullptr } },
        /* functions introduced in GLX 1.1 */
        { (PRFuncPtr*) &xQueryExtensionsStringInternal, { "glXQueryExtensionsString", nullptr } },
        { (PRFuncPtr*) &xGetClientStringInternal, { "glXGetClientString", nullptr } },
        { (PRFuncPtr*) &xQueryServerStringInternal, { "glXQueryServerString", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::SymLoadStruct symbols13[] = {
        /* functions introduced in GLX 1.3 */
        { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfig", nullptr } },
        { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttrib", nullptr } },
        // WARNING: xGetFBConfigs not set in symbols13_ext
        { (PRFuncPtr*) &xGetFBConfigsInternal, { "glXGetFBConfigs", nullptr } },
        // WARNING: symbols13_ext sets xCreateGLXPixmapWithConfig instead
        { (PRFuncPtr*) &xCreatePixmapInternal, { "glXCreatePixmap", nullptr } },
        { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyPixmap", nullptr } },
        { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateNewContext", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::SymLoadStruct symbols13_ext[] = {
        /* extension equivalents for functions introduced in GLX 1.3 */
        // GLX_SGIX_fbconfig extension
        { (PRFuncPtr*) &xChooseFBConfigInternal, { "glXChooseFBConfigSGIX", nullptr } },
        { (PRFuncPtr*) &xGetFBConfigAttribInternal, { "glXGetFBConfigAttribSGIX", nullptr } },
        // WARNING: no xGetFBConfigs equivalent in extensions
        // WARNING: different from symbols13:
        { (PRFuncPtr*) &xCreateGLXPixmapWithConfigInternal, { "glXCreateGLXPixmapWithConfigSGIX", nullptr } },
        { (PRFuncPtr*) &xDestroyPixmapInternal, { "glXDestroyGLXPixmap", nullptr } }, // not from ext
        { (PRFuncPtr*) &xCreateNewContextInternal, { "glXCreateContextWithConfigSGIX", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::SymLoadStruct symbols14[] = {
        /* functions introduced in GLX 1.4 */
        { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddress", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::SymLoadStruct symbols14_ext[] = {
        /* extension equivalents for functions introduced in GLX 1.4 */
        // GLX_ARB_get_proc_address extension
        { (PRFuncPtr*) &xGetProcAddressInternal, { "glXGetProcAddressARB", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::SymLoadStruct symbols_texturefrompixmap[] = {
        { (PRFuncPtr*) &xBindTexImageInternal, { "glXBindTexImageEXT", nullptr } },
        { (PRFuncPtr*) &xReleaseTexImageInternal, { "glXReleaseTexImageEXT", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::SymLoadStruct symbols_robustness[] = {
        { (PRFuncPtr*) &xCreateContextAttribsInternal, { "glXCreateContextAttribsARB", nullptr } },
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
        NS_WARNING("Couldn't find required entry point in OpenGL shared library");
        return false;
    }

    Display *display = DefaultXDisplay();
    int screen = DefaultScreen(display);

    if (!xQueryVersion(display, &mGLXMajorVersion, &mGLXMinorVersion)) {
        mGLXMajorVersion = 0;
        mGLXMinorVersion = 0;
        return false;
    }

    if (!GLXVersionCheck(1, 1))
        // Not possible to query for extensions.
        return false;

    const char *clientVendor = xGetClientString(display, LOCAL_GLX_VENDOR);
    const char *serverVendor = xQueryServerString(display, screen, LOCAL_GLX_VENDOR);
    const char *extensionsStr = xQueryExtensionsString(display, screen);

    GLLibraryLoader::SymLoadStruct *sym13;
    if (!GLXVersionCheck(1, 3)) {
        // Even if we don't have 1.3, we might have equivalent extensions
        // (as on the Intel X server).
        if (!HasExtension(extensionsStr, "GLX_SGIX_fbconfig")) {
            return false;
        }
        sym13 = symbols13_ext;
    } else {
        sym13 = symbols13;
    }
    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym13)) {
        NS_WARNING("Couldn't find required entry point in OpenGL shared library");
        return false;
    }

    GLLibraryLoader::SymLoadStruct *sym14;
    if (!GLXVersionCheck(1, 4)) {
        // Even if we don't have 1.4, we might have equivalent extensions
        // (as on the Intel X server).
        if (!HasExtension(extensionsStr, "GLX_ARB_get_proc_address")) {
            return false;
        }
        sym14 = symbols14_ext;
    } else {
        sym14 = symbols14;
    }
    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym14)) {
        NS_WARNING("Couldn't find required entry point in OpenGL shared library");
        return false;
    }

    if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap, 
                                         (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
    {
#ifdef MOZ_WIDGET_GTK
        mUseTextureFromPixmap = gfxPlatformGtk::GetPlatform()->UseXRender();
#else
        mUseTextureFromPixmap = true;
#endif
    } else {
        mUseTextureFromPixmap = false;
        NS_WARNING("Texture from pixmap disabled");
    }

    if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness") &&
        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) {
        mHasRobustness = true;
    }

    mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI");
    mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation");
    mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa");

    mInitialized = true;
    mLibType = libType;

    return true;
}
Beispiel #14
0
/*
 * load a new module into our address space and initialize it.
 */
SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
    PRLibrary *library = NULL;
    CK_C_GetFunctionList entry = NULL;
    CK_INFO info;
    CK_ULONG slotCount = 0;
    SECStatus rv;
    PRBool alreadyLoaded = PR_FALSE;
    char *disableUnload = NULL;

    if (mod->loaded)
        return SECSuccess;

    /* internal modules get loaded from their internal list */
    if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_TEST_BUILD
        entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
#else
        /*
         * Loads softoken as a dynamic library,
         * even though the rest of NSS assumes this as the "internal" module.
         */
        if (!softokenLib &&
            PR_SUCCESS != PR_CallOnce(&loadSoftokenOnce, &softoken_LoadDSO))
            return SECFailure;

        PR_ATOMIC_INCREMENT(&softokenLoadCount);

        if (mod->isFIPS) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "FC_GetFunctionList");
        } else {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
        }

        if (!entry)
            return SECFailure;
#endif

        if (mod->isModuleDB) {
            mod->moduleDBFunc = (CK_C_GetFunctionList)
#ifdef NSS_TEST_BUILD
                NSC_ModuleDBFunc;
#else
                PR_FindSymbol(softokenLib, "NSC_ModuleDBFunc");
#endif
        }

        if (mod->moduleDBOnly) {
            mod->loaded = PR_TRUE;
            return SECSuccess;
        }
    } else {
        /* Not internal, load the DLL and look up C_GetFunctionList */
        if (mod->dllName == NULL) {
            return SECFailure;
        }

        /* load the library. If this succeeds, then we have to remember to
         * unload the library if anything goes wrong from here on out...
         */
        library = PR_LoadLibrary(mod->dllName);
        mod->library = (void *)library;

        if (library == NULL) {
            return SECFailure;
        }

        /*
         * now we need to get the entry point to find the function pointers
         */
        if (!mod->moduleDBOnly) {
            entry = (CK_C_GetFunctionList)
                PR_FindSymbol(library, "C_GetFunctionList");
        }
        if (mod->isModuleDB) {
            mod->moduleDBFunc = (void *)
                PR_FindSymbol(library, "NSS_ReturnModuleSpecData");
        }
        if (mod->moduleDBFunc == NULL)
            mod->isModuleDB = PR_FALSE;
        if (entry == NULL) {
            if (mod->isModuleDB) {
                mod->loaded = PR_TRUE;
                mod->moduleDBOnly = PR_TRUE;
                return SECSuccess;
            }
            PR_UnloadLibrary(library);
            return SECFailure;
        }
    }

    /*
     * We need to get the function list
     */
    if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
        goto fail;

#ifdef DEBUG_MODULE
    if (PR_TRUE) {
        modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
        if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
            mod->functionList = (void *)nss_InsertDeviceLog(
                (CK_FUNCTION_LIST_PTR)mod->functionList);
        }
    }
#endif

    mod->isThreadSafe = PR_TRUE;

    /* Now we initialize the module */
    rv = secmod_ModuleInit(mod, oldModule, &alreadyLoaded);
    if (rv != SECSuccess) {
        goto fail;
    }

    /* module has been reloaded, this module itself is done,
     * return to the caller */
    if (mod->functionList == NULL) {
        mod->loaded = PR_TRUE; /* technically the module is loaded.. */
        return SECSuccess;
    }

    /* check the version number */
    if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK)
        goto fail2;
    if (info.cryptokiVersion.major != 2)
        goto fail2;
    /* all 2.0 are a priori *not* thread safe */
    if (info.cryptokiVersion.minor < 1) {
        if (!loadSingleThreadedModules) {
            PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
            goto fail2;
        } else {
            mod->isThreadSafe = PR_FALSE;
        }
    }
    mod->cryptokiVersion = info.cryptokiVersion;

    /* If we don't have a common name, get it from the PKCS 11 module */
    if ((mod->commonName == NULL) || (mod->commonName[0] == 0)) {
        mod->commonName = PK11_MakeString(mod->arena, NULL,
                                          (char *)info.libraryDescription, sizeof(info.libraryDescription));
        if (mod->commonName == NULL)
            goto fail2;
    }

    /* initialize the Slots */
    if (PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, NULL, &slotCount) == CKR_OK) {
        CK_SLOT_ID *slotIDs;
        int i;
        CK_RV crv;

        mod->slots = (PK11SlotInfo **)PORT_ArenaAlloc(mod->arena,
                                                      sizeof(PK11SlotInfo *) * slotCount);
        if (mod->slots == NULL)
            goto fail2;

        slotIDs = (CK_SLOT_ID *)PORT_Alloc(sizeof(CK_SLOT_ID) * slotCount);
        if (slotIDs == NULL) {
            goto fail2;
        }
        crv = PK11_GETTAB(mod)->C_GetSlotList(CK_FALSE, slotIDs, &slotCount);
        if (crv != CKR_OK) {
            PORT_Free(slotIDs);
            goto fail2;
        }

        /* Initialize each slot */
        for (i = 0; i < (int)slotCount; i++) {
            mod->slots[i] = PK11_NewSlotInfo(mod);
            PK11_InitSlot(mod, slotIDs[i], mod->slots[i]);
            /* look down the slot info table */
            PK11_LoadSlotList(mod->slots[i], mod->slotInfo, mod->slotInfoCount);
            SECMOD_SetRootCerts(mod->slots[i], mod);
            /* explicitly mark the internal slot as such if IsInternalKeySlot()
             * is set */
            if (secmod_IsInternalKeySlot(mod) && (i == (mod->isFIPS ? 0 : 1))) {
                pk11_SetInternalKeySlotIfFirst(mod->slots[i]);
            }
        }
        mod->slotCount = slotCount;
        mod->slotInfoCount = 0;
        PORT_Free(slotIDs);
    }

    mod->loaded = PR_TRUE;
    mod->moduleID = nextModuleID++;
    return SECSuccess;
fail2:
    if (enforceAlreadyInitializedError || (!alreadyLoaded)) {
        PK11_GETTAB(mod)->C_Finalize(NULL);
    }
fail:
    mod->functionList = NULL;
    disableUnload = PR_GetEnvSecure("NSS_DISABLE_UNLOAD");
    if (library && !disableUnload) {
        PR_UnloadLibrary(library);
    }
    return SECFailure;
}
Beispiel #15
0
static nsresult
gssInit()
{
    nsXPIDLCString libPath;
    nsCOMPtr<nsIPrefBranch> prefs = do_GetService(NS_PREFSERVICE_CONTRACTID);
    if (prefs) {
        prefs->GetCharPref(kNegotiateAuthGssLib, getter_Copies(libPath)); 
        prefs->GetBoolPref(kNegotiateAuthNativeImp, &gssNativeImp); 
    }

    PRLibrary *lib = NULL;

    if (!libPath.IsEmpty()) {
        LOG(("Attempting to load user specified library [%s]\n", libPath.get()));
        gssNativeImp = PR_FALSE;
        lib = PR_LoadLibrary(libPath.get());
    }
    else {
#ifdef XP_WIN
        char *libName = PR_GetLibraryName(NULL, "gssapi32");
        if (libName) {
            lib = PR_LoadLibrary("gssapi32");
            PR_FreeLibraryName(libName);
        }
#else
        
        const char *const libNames[] = {
            "gss",
            "gssapi_krb5",
            "gssapi"
        };
        
        const char *const verLibNames[] = {
            "libgssapi_krb5.so.2", /* MIT - FC, Suse10, Debian */
            "libgssapi.so.4",      /* Heimdal - Suse10, MDK */
            "libgssapi.so.1"       /* Heimdal - Suse9, CITI - FC, MDK, Suse10*/
        };

        for (size_t i = 0; i < NS_ARRAY_LENGTH(verLibNames) && !lib; ++i) {
            lib = PR_LoadLibrary(verLibNames[i]);
 
            /* The CITI libgssapi library calls exit() during
             * initialization if it's not correctly configured. Try to
             * ensure that we never use this library for our GSSAPI
             * support, as its just a wrapper library, anyway.
             * See Bugzilla #325433
             */
            if (lib &&
                PR_FindFunctionSymbol(lib, 
                                      "internal_krb5_gss_initialize") &&
                PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
                LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
                PR_UnloadLibrary(lib);
                lib = NULL;
            }
        }

        for (size_t i = 0; i < NS_ARRAY_LENGTH(libNames) && !lib; ++i) {
            char *libName = PR_GetLibraryName(NULL, libNames[i]);
            if (libName) {
                lib = PR_LoadLibrary(libName);
                PR_FreeLibraryName(libName);

                if (lib &&
                    PR_FindFunctionSymbol(lib, 
                                          "internal_krb5_gss_initialize") &&
                    PR_FindFunctionSymbol(lib, "gssd_pname_to_uid")) {
                    LOG(("CITI libgssapi found, which calls exit(). Skipping\n"));
                    PR_UnloadLibrary(lib);
                    lib = NULL;
                } 
            }
        }
#endif
    }
    
    if (!lib) {
        LOG(("Fail to load gssapi library\n"));
        return NS_ERROR_FAILURE;
    }

    LOG(("Attempting to load gss functions\n"));

    for (size_t i = 0; i < gssFuncItems; ++i) {
        gssFunPtr[i] = PR_FindFunctionSymbol(lib, gssFuncStr[i]);
        if (!gssFunPtr[i]) {
            LOG(("Fail to load %s function from gssapi library\n", gssFuncStr[i]));
            PR_UnloadLibrary(lib);
            return NS_ERROR_FAILURE;
        }
    }
#ifdef XP_MACOSX
    if (gssNativeImp &&
            !(KLCacheHasValidTicketsPtr =
               PR_FindFunctionSymbol(lib, "KLCacheHasValidTickets"))) {
        LOG(("Fail to load KLCacheHasValidTickets function from gssapi library\n"));
        PR_UnloadLibrary(lib);
        return NS_ERROR_FAILURE;
    }
#endif

    gssFunInit = PR_TRUE;
    return NS_OK;
}
PRBool
GConfProxy::Init()
{
    SYSPREF_LOG(("GConfProxy:: Init GConfProxy\n"));
    if (!mSysPrefService)
        return PR_FALSE;
    if (mInitialized)
        return PR_TRUE;

    nsCOMPtr<nsIPref> pref = do_GetService(NS_PREF_CONTRACTID);
    if (!pref)
        return PR_FALSE;

    nsXPIDLCString gconfLibName;
    nsresult rv;

    //check if gconf-2 library is given in prefs
    rv = pref->GetCharPref(sPrefGConfKey, getter_Copies(gconfLibName));
    if (NS_SUCCEEDED(rv)) {
        //use the library name in the preference
        SYSPREF_LOG(("GConf library in prefs is %s\n", gconfLibName.get()));
        mGConfLib = PR_LoadLibrary(gconfLibName.get());
    }
    else {
        SYSPREF_LOG(("GConf library not specified in prefs, try the default: "
                     "%s and %s\n", sDefaultLibName1, sDefaultLibName2));
        mGConfLib = PR_LoadLibrary(sDefaultLibName1);
        if (!mGConfLib)
            mGConfLib = PR_LoadLibrary(sDefaultLibName2);
    }

    if (!mGConfLib) {
        SYSPREF_LOG(("Fail to load GConf library\n"));
        return PR_FALSE;
    }

    //check every func we need in the gconf library
    GConfFuncListType *funcList;
    PRFuncPtr func;
    for (funcList = sGConfFuncList; funcList->FuncName; ++funcList) {
        func = PR_FindFunctionSymbol(mGConfLib, funcList->FuncName);
        if (!func) {
            SYSPREF_LOG(("Check GConf Func Error: %s", funcList->FuncName));
            goto init_failed_unload;
        }
        funcList->FuncPtr = func;
    }

    InitFuncPtrs();

    mGConfClient = GConfClientGetDefault();

    // Don't unload past this point, since GConf's initialization of ORBit
    // causes atexit handlers to be registered.

    if (!mGConfClient) {
        SYSPREF_LOG(("Fail to Get default gconf client\n"));
        goto init_failed;
    }
    mInitialized = PR_TRUE;
    return PR_TRUE;

 init_failed_unload:
    PR_UnloadLibrary(mGConfLib);
 init_failed:
    mGConfLib = nsnull;
    return PR_FALSE;
}
nsresult
nsScreenManagerGtk :: Init()
{
#ifdef MOZ_X11
  XineramaScreenInfo *screenInfo = NULL;
  int numScreens;

  if (!mXineramalib) {
    mXineramalib = PR_LoadLibrary("libXinerama.so.1");
    if (!mXineramalib) {
      mXineramalib = SCREEN_MANAGER_LIBRARY_LOAD_FAILED;
    }
  }
  if (mXineramalib && mXineramalib != SCREEN_MANAGER_LIBRARY_LOAD_FAILED) {
    _XnrmIsActive_fn _XnrmIsActive = (_XnrmIsActive_fn)
        PR_FindFunctionSymbol(mXineramalib, "XineramaIsActive");

    _XnrmQueryScreens_fn _XnrmQueryScreens = (_XnrmQueryScreens_fn)
        PR_FindFunctionSymbol(mXineramalib, "XineramaQueryScreens");
        
    // get the number of screens via xinerama
    if (_XnrmIsActive && _XnrmQueryScreens &&
        _XnrmIsActive(GDK_DISPLAY())) {
      screenInfo = _XnrmQueryScreens(GDK_DISPLAY(), &numScreens);
    }
  }

  // screenInfo == NULL if either Xinerama couldn't be loaded or
  // isn't running on the current display
  if (!screenInfo || numScreens == 1) {
    numScreens = 1;
#endif
    nsRefPtr<nsScreenGtk> screen;

    if (mCachedScreenArray.Count() > 0) {
      screen = static_cast<nsScreenGtk*>(mCachedScreenArray[0]);
    } else {
      screen = new nsScreenGtk();
      if (!screen || !mCachedScreenArray.AppendObject(screen)) {
        return NS_ERROR_OUT_OF_MEMORY;
      }
    }

    screen->Init(mRootWindow);
#ifdef MOZ_X11
  }
  // If Xinerama is enabled and there's more than one screen, fill
  // in the info for all of the screens.  If that's not the case
  // then nsScreenGTK() defaults to the screen width + height
  else {
#ifdef DEBUG
    printf("Xinerama superpowers activated for %d screens!\n", numScreens);
#endif
    for (int i = 0; i < numScreens; ++i) {
      nsRefPtr<nsScreenGtk> screen;
      if (mCachedScreenArray.Count() > i) {
        screen = static_cast<nsScreenGtk*>(mCachedScreenArray[i]);
      } else {
        screen = new nsScreenGtk();
        if (!screen || !mCachedScreenArray.AppendObject(screen)) {
          return NS_ERROR_OUT_OF_MEMORY;
        }
      }

      // initialize this screen object
      screen->Init(&screenInfo[i]);
    }
  }
  // Remove any screens that are no longer present.
  while (mCachedScreenArray.Count() > numScreens) {
    mCachedScreenArray.RemoveObjectAt(mCachedScreenArray.Count() - 1);
  }

  if (screenInfo) {
    XFree(screenInfo);
  }
#endif

  return NS_OK;
}
Beispiel #18
0
int
rmain
(
  int argc,
  char *argv[]
)
{
  char *argv0 = argv[0];
  PRLibrary *lib;
  CK_C_GetFunctionList gfl;
  CK_FUNCTION_LIST_PTR epv = (CK_FUNCTION_LIST_PTR)NULL;
  CK_RV ck_rv;
  CK_INFO info;
  CK_ULONG nSlots;
  CK_SLOT_ID *pSlots;
  CK_ULONG i;
  CK_C_INITIALIZE_ARGS ia, *iap;

  (void)memset(&ia, 0, sizeof(CK_C_INITIALIZE_ARGS));
  iap = (CK_C_INITIALIZE_ARGS *)NULL;
  while( argv++, --argc ) {
    if( '-' == argv[0][0] ) {
      switch( argv[0][1] ) {
      case 'i':
        iap = &ia;
        if( ((char *)NULL != argv[1]) && ('-' != argv[1][0]) ) {
#ifdef WITH_NSS
          ia.pConfig = argv[1];
          ia.ulConfigLen = strlen(argv[1]);
          argv++, --argc;
#else
          return usage(argv0);
#endif /* WITH_NSS */
        }
        break;
      case '-':
        argv++, --argc;
        goto endargs;
      default:
        return usage(argv0);
      }
    } else {
      break;
    }
  }
 endargs:;

  if( 1 != argc ) {
    return usage(argv0);
  }

  lib = PR_LoadLibrary(argv[0]);
  if( (PRLibrary *)NULL == lib ) {
    PR_fprintf(PR_STDERR, "Can't load %s: %ld, %ld\n", argv[1], PR_GetError(), PR_GetOSError());
    return 1;
  }

  gfl = (CK_C_GetFunctionList)PR_FindSymbol(lib, "C_GetFunctionList");
  if( (CK_C_GetFunctionList)NULL == gfl ) {
    PR_fprintf(PR_STDERR, "Can't find C_GetFunctionList in %s: %ld, %ld\n", argv[1], 
               PR_GetError(), PR_GetOSError());
    return 1;
  }

  ck_rv = (*gfl)(&epv);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "CK_GetFunctionList returned 0x%08x\n", ck_rv);
    return 1;
  }

  PR_fprintf(PR_STDOUT, "Module %s loaded, epv = 0x%08x.\n\n", argv[1], (CK_ULONG)epv);

  /* C_Initialize */
  ck_rv = epv->C_Initialize(iap);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "C_Initialize returned 0x%08x\n", ck_rv);
    return 1;
  }

  /* C_GetInfo */
  (void)memset(&info, 0, sizeof(CK_INFO));
  ck_rv = epv->C_GetInfo(&info);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "C_GetInfo returned 0x%08x\n", ck_rv);
    return 1;
  }

  PR_fprintf(PR_STDOUT, "Module Info:\n");
  PR_fprintf(PR_STDOUT, "    cryptokiVersion = %lu.%02lu\n", 
             (PRUint32)info.cryptokiVersion.major, (PRUint32)info.cryptokiVersion.minor);
  PR_fprintf(PR_STDOUT, "    manufacturerID = \"%.32s\"\n", info.manufacturerID);
  PR_fprintf(PR_STDOUT, "    flags = 0x%08lx\n", info.flags);
  PR_fprintf(PR_STDOUT, "    libraryDescription = \"%.32s\"\n", info.libraryDescription);
  PR_fprintf(PR_STDOUT, "    libraryVersion = %lu.%02lu\n", 
             (PRUint32)info.libraryVersion.major, (PRUint32)info.libraryVersion.minor);
  PR_fprintf(PR_STDOUT, "\n");

  /* C_GetSlotList */
  nSlots = 0;
  ck_rv = epv->C_GetSlotList(CK_FALSE, (CK_SLOT_ID_PTR)CK_NULL_PTR, &nSlots);
  switch( ck_rv ) {
  case CKR_BUFFER_TOO_SMALL:
  case CKR_OK:
    break;
  default:
    PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, NULL, ) returned 0x%08x\n", ck_rv);
    return 1;
  }

  PR_fprintf(PR_STDOUT, "There are %lu slots.\n", nSlots);

  pSlots = (CK_SLOT_ID_PTR)PR_Calloc(nSlots, sizeof(CK_SLOT_ID));
  if( (CK_SLOT_ID_PTR)NULL == pSlots ) {
    PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", nSlots * sizeof(CK_SLOT_ID));
    return 1;
  }

  ck_rv = epv->C_GetSlotList(CK_FALSE, pSlots, &nSlots);
  if( CKR_OK != ck_rv ) {
    PR_fprintf(PR_STDERR, "C_GetSlotList(FALSE, , ) returned 0x%08x\n", ck_rv);
    return 1;
  }

  for( i = 0; i < nSlots; i++ ) {
    PR_fprintf(PR_STDOUT, "    [%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]);
  }

  PR_fprintf(PR_STDOUT, "\n");

  /* C_GetSlotInfo */
  for( i = 0; i < nSlots; i++ ) {
    CK_SLOT_INFO sinfo;

    PR_fprintf(PR_STDOUT, "[%lu]: CK_SLOT_ID = %lu\n", (i+1), pSlots[i]);

    (void)memset(&sinfo, 0, sizeof(CK_SLOT_INFO));
    ck_rv = epv->C_GetSlotInfo(pSlots[i], &sinfo);
    if( CKR_OK != ck_rv ) {
      PR_fprintf(PR_STDERR, "C_GetSlotInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv);
      return 1;
    }

    PR_fprintf(PR_STDOUT, "    Slot Info:\n");
    PR_fprintf(PR_STDOUT, "        slotDescription = \"%.64s\"\n", sinfo.slotDescription);
    PR_fprintf(PR_STDOUT, "        manufacturerID = \"%.32s\"\n", sinfo.manufacturerID);
    PR_fprintf(PR_STDOUT, "        flags = 0x%08lx\n", sinfo.flags);
    PR_fprintf(PR_STDOUT, "            -> TOKEN PRESENT = %s\n", 
               sinfo.flags & CKF_TOKEN_PRESENT ? "TRUE" : "FALSE");
    PR_fprintf(PR_STDOUT, "            -> REMOVABLE DEVICE = %s\n",
               sinfo.flags & CKF_REMOVABLE_DEVICE ? "TRUE" : "FALSE");
    PR_fprintf(PR_STDOUT, "            -> HW SLOT = %s\n", 
               sinfo.flags & CKF_HW_SLOT ? "TRUE" : "FALSE");
    PR_fprintf(PR_STDOUT, "        hardwareVersion = %lu.%02lu\n", 
               (PRUint32)sinfo.hardwareVersion.major, (PRUint32)sinfo.hardwareVersion.minor);
    PR_fprintf(PR_STDOUT, "        firmwareVersion = %lu.%02lu\n",
               (PRUint32)sinfo.firmwareVersion.major, (PRUint32)sinfo.firmwareVersion.minor);

    if( sinfo.flags & CKF_TOKEN_PRESENT ) {
      CK_TOKEN_INFO tinfo;
      CK_MECHANISM_TYPE *pMechanismList;
      CK_ULONG nMechanisms = 0;
      CK_ULONG j;

      (void)memset(&tinfo, 0, sizeof(CK_TOKEN_INFO));
      ck_rv = epv->C_GetTokenInfo(pSlots[i], &tinfo);
      if( CKR_OK != ck_rv ) {
        PR_fprintf(PR_STDERR, "C_GetTokenInfo(%lu, ) returned 0x%08x\n", pSlots[i], ck_rv);
        return 1;
      }

      PR_fprintf(PR_STDOUT, "    Token Info:\n");
      PR_fprintf(PR_STDOUT, "        label = \"%.32s\"\n", tinfo.label);
      PR_fprintf(PR_STDOUT, "        manufacturerID = \"%.32s\"\n", tinfo.manufacturerID);
      PR_fprintf(PR_STDOUT, "        model = \"%.16s\"\n", tinfo.model);
      PR_fprintf(PR_STDOUT, "        serialNumber = \"%.16s\"\n", tinfo.serialNumber);
      PR_fprintf(PR_STDOUT, "        flags = 0x%08lx\n", tinfo.flags);
      PR_fprintf(PR_STDOUT, "            -> RNG = %s\n",
                 tinfo.flags & CKF_RNG ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> WRITE PROTECTED = %s\n",
                 tinfo.flags & CKF_WRITE_PROTECTED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> LOGIN REQUIRED = %s\n",
                 tinfo.flags & CKF_LOGIN_REQUIRED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> USER PIN INITIALIZED = %s\n",
                 tinfo.flags & CKF_USER_PIN_INITIALIZED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> RESTORE KEY NOT NEEDED = %s\n",
                 tinfo.flags & CKF_RESTORE_KEY_NOT_NEEDED ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> CLOCK ON TOKEN = %s\n",
                 tinfo.flags & CKF_CLOCK_ON_TOKEN ? "TRUE" : "FALSE");
#ifdef CKF_SUPPORTS_PARALLEL
      PR_fprintf(PR_STDOUT, "            -> SUPPORTS PARALLEL = %s\n",
                 tinfo.flags & CKF_SUPPORTS_PARALLEL ? "TRUE" : "FALSE");
#endif /* CKF_SUPPORTS_PARALLEL */
      PR_fprintf(PR_STDOUT, "            -> PROTECTED AUTHENTICATION PATH = %s\n",
                 tinfo.flags & CKF_PROTECTED_AUTHENTICATION_PATH ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "            -> DUAL_CRYPTO_OPERATIONS = %s\n", 
                 tinfo.flags & CKF_DUAL_CRYPTO_OPERATIONS ? "TRUE" : "FALSE");
      PR_fprintf(PR_STDOUT, "        ulMaxSessionCount = %lu\n", tinfo.ulMaxSessionCount);
      PR_fprintf(PR_STDOUT, "        ulSessionCount = %lu\n", tinfo.ulSessionCount);
      PR_fprintf(PR_STDOUT, "        ulMaxRwSessionCount = %lu\n", tinfo.ulMaxRwSessionCount);
      PR_fprintf(PR_STDOUT, "        ulRwSessionCount = %lu\n", tinfo.ulRwSessionCount);
      PR_fprintf(PR_STDOUT, "        ulMaxPinLen = %lu\n", tinfo.ulMaxPinLen);
      PR_fprintf(PR_STDOUT, "        ulMinPinLen = %lu\n", tinfo.ulMinPinLen);
      PR_fprintf(PR_STDOUT, "        ulTotalPublicMemory = %lu\n", tinfo.ulTotalPublicMemory);
      PR_fprintf(PR_STDOUT, "        ulFreePublicMemory = %lu\n", tinfo.ulFreePublicMemory);
      PR_fprintf(PR_STDOUT, "        ulTotalPrivateMemory = %lu\n", tinfo.ulTotalPrivateMemory);
      PR_fprintf(PR_STDOUT, "        ulFreePrivateMemory = %lu\n", tinfo.ulFreePrivateMemory);
      PR_fprintf(PR_STDOUT, "        hardwareVersion = %lu.%02lu\n", 
                 (PRUint32)tinfo.hardwareVersion.major, (PRUint32)tinfo.hardwareVersion.minor);
      PR_fprintf(PR_STDOUT, "        firmwareVersion = %lu.%02lu\n",
                 (PRUint32)tinfo.firmwareVersion.major, (PRUint32)tinfo.firmwareVersion.minor);
      PR_fprintf(PR_STDOUT, "        utcTime = \"%.16s\"\n", tinfo.utcTime);


      ck_rv = epv->C_GetMechanismList(pSlots[i], (CK_MECHANISM_TYPE_PTR)CK_NULL_PTR, &nMechanisms);
      switch( ck_rv ) {
      case CKR_BUFFER_TOO_SMALL:
      case CKR_OK:
        break;
      default:
        PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, NULL, ) returned 0x%08x\n", pSlots[i], ck_rv);
        return 1;
      }

      PR_fprintf(PR_STDOUT, "    %lu mechanisms:\n", nMechanisms);

      pMechanismList = (CK_MECHANISM_TYPE_PTR)PR_Calloc(nMechanisms, sizeof(CK_MECHANISM_TYPE));
      if( (CK_MECHANISM_TYPE_PTR)NULL == pMechanismList ) {
        PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", 
                   nMechanisms * sizeof(CK_MECHANISM_TYPE));
        return 1;
      }

      ck_rv = epv->C_GetMechanismList(pSlots[i], pMechanismList, &nMechanisms);
      if( CKR_OK != ck_rv ) {
        PR_fprintf(PR_STDERR, "C_GetMechanismList(%lu, , ) returned 0x%08x\n", pSlots[i], ck_rv);
        return 1;
      }

      for( j = 0; j < nMechanisms; j++ ) {
        PR_fprintf(PR_STDOUT, "        {%lu}: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]);
      }

      PR_fprintf(PR_STDOUT, "\n");

      for( j = 0; j < nMechanisms; j++ ) {
        CK_MECHANISM_INFO minfo;

        (void)memset(&minfo, 0, sizeof(CK_MECHANISM_INFO));
        ck_rv = epv->C_GetMechanismInfo(pSlots[i], pMechanismList[j], &minfo);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_GetMechanismInfo(%lu, %lu, ) returned 0x%08x\n", pSlots[i], 
                     pMechanismList[j]);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    [%lu]: CK_MECHANISM_TYPE = %lu\n", (j+1), pMechanismList[j]);
        PR_fprintf(PR_STDOUT, "    ulMinKeySize = %lu\n", minfo.ulMinKeySize);
        PR_fprintf(PR_STDOUT, "    ulMaxKeySize = %lu\n", minfo.ulMaxKeySize);
        PR_fprintf(PR_STDOUT, "    flags = 0x%08x\n", minfo.flags);
        PR_fprintf(PR_STDOUT, "        -> HW = %s\n", minfo.flags & CKF_HW ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> ENCRYPT = %s\n", minfo.flags & CKF_ENCRYPT ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> DECRYPT = %s\n", minfo.flags & CKF_DECRYPT ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> DIGEST = %s\n", minfo.flags & CKF_DIGEST ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> SIGN = %s\n", minfo.flags & CKF_SIGN ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> SIGN_RECOVER = %s\n", minfo.flags & CKF_SIGN_RECOVER ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> VERIFY = %s\n", minfo.flags & CKF_VERIFY ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> VERIFY_RECOVER = %s\n", minfo.flags & CKF_VERIFY_RECOVER ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> GENERATE = %s\n", minfo.flags & CKF_GENERATE ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> GENERATE_KEY_PAIR = %s\n", minfo.flags & CKF_GENERATE_KEY_PAIR ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> WRAP = %s\n", minfo.flags & CKF_WRAP ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> UNWRAP = %s\n", minfo.flags & CKF_UNWRAP ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> DERIVE = %s\n", minfo.flags & CKF_DERIVE ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "        -> EXTENSION = %s\n", minfo.flags & CKF_EXTENSION ? "TRUE" : "FALSE");

        PR_fprintf(PR_STDOUT, "\n");
      }

      if( tinfo.flags & CKF_LOGIN_REQUIRED ) {
        PR_fprintf(PR_STDERR, "*** LOGIN REQUIRED but not yet implemented ***\n");
        /* all the stuff about logging in as SO and setting the user pin if needed, etc. */
        return 2;
      }

      /* session to find objects */
      {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_SESSION_INFO sinfo;
        CK_ATTRIBUTE_PTR pTemplate;
        CK_ULONG tnObjects = 0;

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        (void)memset(&sinfo, 0, sizeof(CK_SESSION_INFO));
        ck_rv = epv->C_GetSessionInfo(h, &sinfo);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDOUT, "C_GetSessionInfo(%lu, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    SESSION INFO:\n");
        PR_fprintf(PR_STDOUT, "        slotID = %lu\n", sinfo.slotID);
        PR_fprintf(PR_STDOUT, "        state = %lu\n", sinfo.state);
        PR_fprintf(PR_STDOUT, "        flags = 0x%08x\n", sinfo.flags);
#ifdef CKF_EXCLUSIVE_SESSION
        PR_fprintf(PR_STDOUT, "            -> EXCLUSIVE SESSION = %s\n", sinfo.flags & CKF_EXCLUSIVE_SESSION ? "TRUE" : "FALSE");
#endif /* CKF_EXCLUSIVE_SESSION */
        PR_fprintf(PR_STDOUT, "            -> RW SESSION = %s\n", sinfo.flags & CKF_RW_SESSION ? "TRUE" : "FALSE");
        PR_fprintf(PR_STDOUT, "            -> SERIAL SESSION = %s\n", sinfo.flags & CKF_SERIAL_SESSION ? "TRUE" : "FALSE");
#ifdef CKF_INSERTION_CALLBACK
        PR_fprintf(PR_STDOUT, "            -> INSERTION CALLBACK = %s\n", sinfo.flags & CKF_INSERTION_CALLBACK ? "TRUE" : "FALSE");
#endif /* CKF_INSERTION_CALLBACK */
        PR_fprintf(PR_STDOUT, "        ulDeviceError = %lu\n", sinfo.ulDeviceError);
        PR_fprintf(PR_STDOUT, "\n");

        ck_rv = epv->C_FindObjectsInit(h, (CK_ATTRIBUTE_PTR)CK_NULL_PTR, 0);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDOUT, "C_FindObjectsInit(%lu, NULL_PTR, 0) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        pTemplate = (CK_ATTRIBUTE_PTR)PR_Calloc(number_of_all_known_attribute_types, sizeof(CK_ATTRIBUTE));
        if( (CK_ATTRIBUTE_PTR)NULL == pTemplate ) {
          PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", 
                     number_of_all_known_attribute_types * sizeof(CK_ATTRIBUTE));
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    All objects:\n");

        while(1) {
          CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
          CK_ULONG nObjects = 0;
          CK_ULONG k;
          CK_ULONG nAttributes = 0;
          CK_ATTRIBUTE_PTR pT2;
          CK_ULONG l;

          ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv);
            return 1;
          }

          if( 0 == nObjects ) {
            PR_fprintf(PR_STDOUT, "\n");
            break;
          }

          tnObjects++;

          PR_fprintf(PR_STDOUT, "        OBJECT HANDLE %lu:\n", o);

          for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
            pTemplate[k].type = all_known_attribute_types[k];
            pTemplate[k].pValue = (CK_VOID_PTR)CK_NULL_PTR;
            pTemplate[k].ulValueLen = 0;
          }

          ck_rv = epv->C_GetAttributeValue(h, o, pTemplate, number_of_all_known_attribute_types);
          switch( ck_rv ) {
          case CKR_OK:
          case CKR_ATTRIBUTE_SENSITIVE:
          case CKR_ATTRIBUTE_TYPE_INVALID:
          case CKR_BUFFER_TOO_SMALL:
            break;
          default:
            PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {all attribute types}, %lu) returned 0x%08x\n",
                       h, o, number_of_all_known_attribute_types, ck_rv);
            return 1;
          }

          for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
            if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
              nAttributes++;
            }
          }

          if( 1 ) {
            PR_fprintf(PR_STDOUT, "            %lu attributes:\n", nAttributes);
            for( k = 0; k < number_of_all_known_attribute_types; k++ ) {
              if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
                PR_fprintf(PR_STDOUT, "                0x%08x (len = %lu)\n", pTemplate[k].type, 
                           pTemplate[k].ulValueLen);
              }
            }
            PR_fprintf(PR_STDOUT, "\n");
          }

          pT2 = (CK_ATTRIBUTE_PTR)PR_Calloc(nAttributes, sizeof(CK_ATTRIBUTE));
          if( (CK_ATTRIBUTE_PTR)NULL == pT2 ) {
            PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", 
                       nAttributes * sizeof(CK_ATTRIBUTE));
            return 1;
          }

          for( l = 0, k = 0; k < number_of_all_known_attribute_types; k++ ) {
            if( -1 != (CK_LONG)pTemplate[k].ulValueLen ) {
              pT2[l].type = pTemplate[k].type;
              pT2[l].ulValueLen = pTemplate[k].ulValueLen;
              pT2[l].pValue = (CK_VOID_PTR)PR_Malloc(pT2[l].ulValueLen);
              if( (CK_VOID_PTR)NULL == pT2[l].pValue ) {
                PR_fprintf(PR_STDERR, "[memory allocation of %lu bytes failed]\n", pT2[l].ulValueLen);
                return 1;
              }
              l++;
            }
          }

          PR_ASSERT( l == nAttributes );

          ck_rv = epv->C_GetAttributeValue(h, o, pT2, nAttributes);
          switch( ck_rv ) {
          case CKR_OK:
          case CKR_ATTRIBUTE_SENSITIVE:
          case CKR_ATTRIBUTE_TYPE_INVALID:
          case CKR_BUFFER_TOO_SMALL:
            break;
          default:
            PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, {existent attribute types}, %lu) returned 0x%08x\n",
                       h, o, nAttributes, ck_rv);
            return 1;
          }

          for( l = 0; l < nAttributes; l++ ) {
            PR_fprintf(PR_STDOUT, "            type = 0x%08x, len = %ld", pT2[l].type, (CK_LONG)pT2[l].ulValueLen);
            if( -1 == (CK_LONG)pT2[l].ulValueLen ) {
              ;
            } else {
              CK_ULONG m;

              if( pT2[l].ulValueLen <= 8 ) {
                PR_fprintf(PR_STDOUT, ", value = ");
              } else {
                PR_fprintf(PR_STDOUT, ", value = \n                ");
              }

              for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
                PR_fprintf(PR_STDOUT, "%02x", (CK_ULONG)(0xff & ((CK_CHAR_PTR)pT2[l].pValue)[m]));
              }

              PR_fprintf(PR_STDOUT, " ");

              for( m = 0; (m < pT2[l].ulValueLen) && (m < 20); m++ ) {
                CK_CHAR c = ((CK_CHAR_PTR)pT2[l].pValue)[m];
                if( (c < 0x20) || (c >= 0x7f) ) {
                  c = '.';
                }
                PR_fprintf(PR_STDOUT, "%c", c);
              }
            }

            PR_fprintf(PR_STDOUT, "\n");
          }
          
          PR_fprintf(PR_STDOUT, "\n");

          for( l = 0; l < nAttributes; l++ ) {
            PR_Free(pT2[l].pValue);
          }
          PR_Free(pT2);
        } /* while(1) */

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    (%lu objects total)\n", tnObjects);

        ck_rv = epv->C_CloseSession(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }
      } /* session to find objects */

      /* session to create, find, and delete a couple session objects */
      {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_ATTRIBUTE one[7], two[7], three[7], delta[1], mask[1];
        CK_OBJECT_CLASS cko_data = CKO_DATA;
        CK_BBOOL false = CK_FALSE, true = CK_TRUE;
        char *key = "TEST PROGRAM";
        CK_ULONG key_len = strlen(key);
        CK_OBJECT_HANDLE hOneIn = (CK_OBJECT_HANDLE)0, hTwoIn = (CK_OBJECT_HANDLE)0, 
          hThreeIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0;
        CK_OBJECT_HANDLE found[10];
        CK_ULONG nFound;

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        one[0].type = CKA_CLASS;
        one[0].pValue = &cko_data;
        one[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        one[1].type = CKA_TOKEN;
        one[1].pValue = &false;
        one[1].ulValueLen = sizeof(CK_BBOOL);
        one[2].type = CKA_PRIVATE;
        one[2].pValue = &false;
        one[2].ulValueLen = sizeof(CK_BBOOL);
        one[3].type = CKA_MODIFIABLE;
        one[3].pValue = &true;
        one[3].ulValueLen = sizeof(CK_BBOOL);
        one[4].type = CKA_LABEL;
        one[4].pValue = "Test data object one";
        one[4].ulValueLen = strlen(one[4].pValue);
        one[5].type = CKA_APPLICATION;
        one[5].pValue = key;
        one[5].ulValueLen = key_len;
        one[6].type = CKA_VALUE;
        one[6].pValue = "Object one";
        one[6].ulValueLen = strlen(one[6].pValue);

        two[0].type = CKA_CLASS;
        two[0].pValue = &cko_data;
        two[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        two[1].type = CKA_TOKEN;
        two[1].pValue = &false;
        two[1].ulValueLen = sizeof(CK_BBOOL);
        two[2].type = CKA_PRIVATE;
        two[2].pValue = &false;
        two[2].ulValueLen = sizeof(CK_BBOOL);
        two[3].type = CKA_MODIFIABLE;
        two[3].pValue = &true;
        two[3].ulValueLen = sizeof(CK_BBOOL);
        two[4].type = CKA_LABEL;
        two[4].pValue = "Test data object two";
        two[4].ulValueLen = strlen(two[4].pValue);
        two[5].type = CKA_APPLICATION;
        two[5].pValue = key;
        two[5].ulValueLen = key_len;
        two[6].type = CKA_VALUE;
        two[6].pValue = "Object two";
        two[6].ulValueLen = strlen(two[6].pValue);

        three[0].type = CKA_CLASS;
        three[0].pValue = &cko_data;
        three[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        three[1].type = CKA_TOKEN;
        three[1].pValue = &false;
        three[1].ulValueLen = sizeof(CK_BBOOL);
        three[2].type = CKA_PRIVATE;
        three[2].pValue = &false;
        three[2].ulValueLen = sizeof(CK_BBOOL);
        three[3].type = CKA_MODIFIABLE;
        three[3].pValue = &true;
        three[3].ulValueLen = sizeof(CK_BBOOL);
        three[4].type = CKA_LABEL;
        three[4].pValue = "Test data object three";
        three[4].ulValueLen = strlen(three[4].pValue);
        three[5].type = CKA_APPLICATION;
        three[5].pValue = key;
        three[5].ulValueLen = key_len;
        three[6].type = CKA_VALUE;
        three[6].pValue = "Object three";
        three[6].ulValueLen = strlen(three[6].pValue);

        ck_rv = epv->C_CreateObject(h, one, 7, &hOneIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, one, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object one: handle = %lu\n", hOneIn);

        ck_rv = epv->C_CreateObject(h, two, 7, &hTwoIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, two, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object two: handle = %lu\n", hTwoIn);

        ck_rv = epv->C_CreateObject(h, three, 7, &hThreeIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, three, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object three: handle = %lu\n", hThreeIn);

        delta[0].type = CKA_VALUE;
        delta[0].pValue = "Copied object";
        delta[0].ulValueLen = strlen(delta[0].pValue);

        ck_rv = epv->C_CopyObject(h, hThreeIn, delta, 1, &hDeltaIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CopyObject(%lu, %lu, delta, 1, ) returned 0x%08x\n", 
                     h, hThreeIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Copied object three: new handle = %lu\n", hDeltaIn);

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;

        ck_rv = epv->C_FindObjectsInit(h, mask, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 4 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 4.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 4 objects: %lu, %lu, %lu, %lu\n", 
                   found[0], found[1], found[2], found[3]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        ck_rv = epv->C_DestroyObject(h, hThreeIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, hThreeIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Destroyed object three (handle = %lu)\n", hThreeIn);

        delta[0].type = CKA_APPLICATION;
        delta[0].pValue = "Changed application";
        delta[0].ulValueLen = strlen(delta[0].pValue);

        ck_rv = epv->C_SetAttributeValue(h, hTwoIn, delta, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", 
                     h, hTwoIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Changed object two (handle = %lu).\n", hTwoIn);

        /* Can another session find these session objects? */
        {
          CK_SESSION_HANDLE h2 = (CK_SESSION_HANDLE)0;

          ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h2);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
            return 1;
          }

          PR_fprintf(PR_STDOUT, "    Opened a second session: handle = 0x%08x\n", h2);

          /* mask is still the same */

          ck_rv = epv->C_FindObjectsInit(h2, mask, 1);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", 
                       h2, ck_rv);
            return 1;
          }

          (void)memset(&found, 0, sizeof(found));
          nFound = 0;
          ck_rv = epv->C_FindObjects(h2, found, 10, &nFound);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                       h2, ck_rv);
            return 1;
          }

          if( 2 != nFound ) {
            PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound);
            return 1;
          }

          PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lu\n", 
                     found[0], found[1]);

          ck_rv = epv->C_FindObjectsFinal(h2);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h2, ck_rv);
            return 1;
          }

          /* Leave the session hanging open, we'll CloseAllSessions later */
        } /* Can another session find these session objects? */

        ck_rv = epv->C_CloseAllSessions(pSlots[i]);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CloseAllSessions(%lu) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }
      } /* session to create, find, and delete a couple session objects */

      /* Might be interesting to do a find here to verify that all session objects are gone. */

      if( tinfo.flags & CKF_WRITE_PROTECTED ) {
        PR_fprintf(PR_STDOUT, "Token is write protected, skipping token-object tests.\n");
      } else {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_ATTRIBUTE tobj[7], tsobj[7], stobj[7], delta[1], mask[2];
        CK_OBJECT_CLASS cko_data = CKO_DATA;
        CK_BBOOL false = CK_FALSE, true = CK_TRUE;
        char *key = "TEST PROGRAM";
        CK_ULONG key_len = strlen(key);
        CK_OBJECT_HANDLE hTIn = (CK_OBJECT_HANDLE)0, hTSIn = (CK_OBJECT_HANDLE)0, 
          hSTIn = (CK_OBJECT_HANDLE)0, hDeltaIn = (CK_OBJECT_HANDLE)0;
        CK_OBJECT_HANDLE found[10];
        CK_ULONG nFound;

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        tobj[0].type = CKA_CLASS;
        tobj[0].pValue = &cko_data;
        tobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        tobj[1].type = CKA_TOKEN;
        tobj[1].pValue = &true;
        tobj[1].ulValueLen = sizeof(CK_BBOOL);
        tobj[2].type = CKA_PRIVATE;
        tobj[2].pValue = &false;
        tobj[2].ulValueLen = sizeof(CK_BBOOL);
        tobj[3].type = CKA_MODIFIABLE;
        tobj[3].pValue = &true;
        tobj[3].ulValueLen = sizeof(CK_BBOOL);
        tobj[4].type = CKA_LABEL;
        tobj[4].pValue = "Test data object token";
        tobj[4].ulValueLen = strlen(tobj[4].pValue);
        tobj[5].type = CKA_APPLICATION;
        tobj[5].pValue = key;
        tobj[5].ulValueLen = key_len;
        tobj[6].type = CKA_VALUE;
        tobj[6].pValue = "Object token";
        tobj[6].ulValueLen = strlen(tobj[6].pValue);

        tsobj[0].type = CKA_CLASS;
        tsobj[0].pValue = &cko_data;
        tsobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        tsobj[1].type = CKA_TOKEN;
        tsobj[1].pValue = &true;
        tsobj[1].ulValueLen = sizeof(CK_BBOOL);
        tsobj[2].type = CKA_PRIVATE;
        tsobj[2].pValue = &false;
        tsobj[2].ulValueLen = sizeof(CK_BBOOL);
        tsobj[3].type = CKA_MODIFIABLE;
        tsobj[3].pValue = &true;
        tsobj[3].ulValueLen = sizeof(CK_BBOOL);
        tsobj[4].type = CKA_LABEL;
        tsobj[4].pValue = "Test data object token->session";
        tsobj[4].ulValueLen = strlen(tsobj[4].pValue);
        tsobj[5].type = CKA_APPLICATION;
        tsobj[5].pValue = key;
        tsobj[5].ulValueLen = key_len;
        tsobj[6].type = CKA_VALUE;
        tsobj[6].pValue = "Object token->session";
        tsobj[6].ulValueLen = strlen(tsobj[6].pValue);

        stobj[0].type = CKA_CLASS;
        stobj[0].pValue = &cko_data;
        stobj[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        stobj[1].type = CKA_TOKEN;
        stobj[1].pValue = &false;
        stobj[1].ulValueLen = sizeof(CK_BBOOL);
        stobj[2].type = CKA_PRIVATE;
        stobj[2].pValue = &false;
        stobj[2].ulValueLen = sizeof(CK_BBOOL);
        stobj[3].type = CKA_MODIFIABLE;
        stobj[3].pValue = &true;
        stobj[3].ulValueLen = sizeof(CK_BBOOL);
        stobj[4].type = CKA_LABEL;
        stobj[4].pValue = "Test data object session->token";
        stobj[4].ulValueLen = strlen(stobj[4].pValue);
        stobj[5].type = CKA_APPLICATION;
        stobj[5].pValue = key;
        stobj[5].ulValueLen = key_len;
        stobj[6].type = CKA_VALUE;
        stobj[6].pValue = "Object session->token";
        stobj[6].ulValueLen = strlen(stobj[6].pValue);

        ck_rv = epv->C_CreateObject(h, tobj, 7, &hTIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object token: handle = %lu\n", hTIn);

        ck_rv = epv->C_CreateObject(h, tsobj, 7, &hTSIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object token->session: handle = %lu\n", hTSIn);
        ck_rv = epv->C_CreateObject(h, stobj, 7, &hSTIn);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created object session->token: handle = %lu\n", hSTIn);

        /* I've created two token objects and one session object; find the two */

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;
        mask[1].type = CKA_TOKEN;
        mask[1].pValue = &true;
        mask[1].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 2 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lu\n", 
                   found[0], found[1]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        /* Convert a token to session object */

        delta[0].type = CKA_TOKEN;
        delta[0].pValue = &false;
        delta[0].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_SetAttributeValue(h, hTSIn, delta, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", 
                     h, hTSIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Changed object from token to session (handle = %lu).\n", hTSIn);

        /* Now find again; there should be one */

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;
        mask[1].type = CKA_TOKEN;
        mask[1].pValue = &true;
        mask[1].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 1 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 1.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 1 objects: %lu\n", 
                   found[0]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        /* Convert a session to a token object */

        delta[0].type = CKA_TOKEN;
        delta[0].pValue = &true;
        delta[0].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_SetAttributeValue(h, hSTIn, delta, 1);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_SetAttributeValue(%lu, %lu, delta, 1) returned 0x%08x\n", 
                     h, hSTIn, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Changed object from session to token (handle = %lu).\n", hSTIn);

        /* Now find again; there should be two again */

        mask[0].type = CKA_APPLICATION;
        mask[0].pValue = key;
        mask[0].ulValueLen = key_len;
        mask[1].type = CKA_TOKEN;
        mask[1].pValue = &true;
        mask[1].ulValueLen = sizeof(CK_BBOOL);

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 2) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        (void)memset(&found, 0, sizeof(found));
        nFound = 0;
        ck_rv = epv->C_FindObjects(h, found, 10, &nFound);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjects(%lu,, 10, ) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        if( 2 != nFound ) {
          PR_fprintf(PR_STDERR, "Found %lu objects, not 2.\n", nFound);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Found 2 objects: %lu, %lu\n", 
                   found[0], found[1]);

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        /* Delete the two (found) token objects to clean up */

        ck_rv = epv->C_DestroyObject(h, found[0]);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[0], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Destroyed token object (handle = %lu)\n", found[0]);

        ck_rv = epv->C_DestroyObject(h, found[1]);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_DestroyObject(%lu, %lu) returned 0x%08x\n", h, found[1], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Destroyed token object (handle = %lu)\n", found[1]);
        
        /* Close the session and all objects should be gone */

        ck_rv = epv->C_CloseSession(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CloseSession(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }
      } /* if( tinfo.flags & CKF_WRITE_PROTECTED ) */

      if( tinfo.flags & CKF_WRITE_PROTECTED ) {
        PR_fprintf(PR_STDOUT, "Token is write protected, skipping leaving a record.\n");
      } else {
        CK_SESSION_HANDLE h = (CK_SESSION_HANDLE)0;
        CK_ATTRIBUTE record[7], mask[2];
        CK_OBJECT_CLASS cko_data = CKO_DATA;
        CK_BBOOL false = CK_FALSE, true = CK_TRUE;
        char *key = "TEST RECORD";
        CK_ULONG key_len = strlen(key);
        CK_OBJECT_HANDLE hin = (CK_OBJECT_HANDLE)0;
        char timebuffer[256];

        ck_rv = epv->C_OpenSession(pSlots[i], CKF_SERIAL_SESSION, (CK_VOID_PTR)CK_NULL_PTR, (CK_NOTIFY)CK_NULL_PTR, &h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_OpenSession(%lu, CKF_SERIAL_SESSION, , ) returned 0x%08x\n", pSlots[i], ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Opened a session: handle = 0x%08x\n", h);

        /* I can't believe how hard NSPR makes this operation */
        {
          time_t now = 0;
          struct tm *tm;
          time(&now);
          tm = localtime(&now);
          strftime(timebuffer, sizeof(timebuffer), "%Y-%m-%d %T %Z", tm);
        }

        record[0].type = CKA_CLASS;
        record[0].pValue = &cko_data;
        record[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        record[1].type = CKA_TOKEN;
        record[1].pValue = &true;
        record[1].ulValueLen = sizeof(CK_BBOOL);
        record[2].type = CKA_PRIVATE;
        record[2].pValue = &false;
        record[2].ulValueLen = sizeof(CK_BBOOL);
        record[3].type = CKA_MODIFIABLE;
        record[3].pValue = &true;
        record[3].ulValueLen = sizeof(CK_BBOOL);
        record[4].type = CKA_LABEL;
        record[4].pValue = "Test record";
        record[4].ulValueLen = strlen(record[4].pValue);
        record[5].type = CKA_APPLICATION;
        record[5].pValue = key;
        record[5].ulValueLen = key_len;
        record[6].type = CKA_VALUE;
        record[6].pValue = timebuffer;
        record[6].ulValueLen = strlen(timebuffer)+1;

        PR_fprintf(PR_STDOUT, "    Timestamping with \"%s\"\n", timebuffer);

        ck_rv = epv->C_CreateObject(h, record, 7, &hin);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_CreateObject(%lu, tobj, 7, ) returned 0x%08x\n", h, ck_rv);
          return 1;
        }

        PR_fprintf(PR_STDOUT, "    Created record object: handle = %lu\n", hin);
        
        PR_fprintf(PR_STDOUT, "   == All test timestamps ==\n");

        mask[0].type = CKA_CLASS;
        mask[0].pValue = &cko_data;
        mask[0].ulValueLen = sizeof(CK_OBJECT_CLASS);
        mask[1].type = CKA_APPLICATION;
        mask[1].pValue = key;
        mask[1].ulValueLen = key_len;

        ck_rv = epv->C_FindObjectsInit(h, mask, 2);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsInit(%lu, mask, 1) returned 0x%08x\n", 
                     h, ck_rv);
          return 1;
        }

        while( 1 ) {
          CK_OBJECT_HANDLE o = (CK_OBJECT_HANDLE)0;
          CK_ULONG nObjects = 0;
          CK_ATTRIBUTE value[1];
          char buffer[1024];

          ck_rv = epv->C_FindObjects(h, &o, 1, &nObjects);
          if( CKR_OK != ck_rv ) {
            PR_fprintf(PR_STDERR, "C_FindObjects(%lu, , 1, ) returned 0x%08x\n", h, ck_rv);
            return 1;
          }

          if( 0 == nObjects ) {
            PR_fprintf(PR_STDOUT, "\n");
            break;
          }

          value[0].type = CKA_VALUE;
          value[0].pValue = buffer;
          value[0].ulValueLen = sizeof(buffer);

          ck_rv = epv->C_GetAttributeValue(h, o, value, 1);
          switch( ck_rv ) {
          case CKR_OK:
            PR_fprintf(PR_STDOUT, "    %s\n", value[0].pValue);
            break;
          case CKR_ATTRIBUTE_SENSITIVE:
            PR_fprintf(PR_STDOUT, "    [Sensitive???]\n");
            break;
          case CKR_ATTRIBUTE_TYPE_INVALID:
            PR_fprintf(PR_STDOUT, "    [Invalid attribute???]\n");
            break;
          case CKR_BUFFER_TOO_SMALL:
            PR_fprintf(PR_STDOUT, "    (result > 1k (%lu))\n", value[0].ulValueLen);
            break;
          default:
            PR_fprintf(PR_STDERR, "C_GetAtributeValue(%lu, %lu, CKA_VALUE, 1) returned 0x%08x\n",
                       h, o);
            return 1;
          }
        } /* while */

        ck_rv = epv->C_FindObjectsFinal(h);
        if( CKR_OK != ck_rv ) {
          PR_fprintf(PR_STDERR, "C_FindObjectsFinal(%lu) returned 0x%08x\n", h, ck_rv);
          return 1;
        }
      } /* "leaving a record" else clause */

    }

    PR_fprintf(PR_STDOUT, "\n");
  }

  return 0;
}
PRBool
GLXLibrary::EnsureInitialized()
{
    if (mInitialized) {
        return PR_TRUE;
    }

    if (!mOGLLibrary) {
        mOGLLibrary = PR_LoadLibrary("libGL.so.1");
        if (!mOGLLibrary) {
	    NS_WARNING("Couldn't load OpenGL shared library.");
	    return PR_FALSE;
        }
    }

    LibrarySymbolLoader::SymLoadStruct symbols[] = {
        { (PRFuncPtr*) &xDeleteContext, { "glXDestroyContext", NULL } },
        { (PRFuncPtr*) &xMakeCurrent, { "glXMakeCurrent", NULL } },
        { (PRFuncPtr*) &xGetProcAddress, { "glXGetProcAddress", NULL } },
        { (PRFuncPtr*) &xChooseVisual, { "glXChooseVisual", NULL } },
        { (PRFuncPtr*) &xChooseFBConfig, { "glXChooseFBConfig", NULL } },
        { (PRFuncPtr*) &xGetFBConfigs, { "glXGetFBConfigs", NULL } },
        { (PRFuncPtr*) &xCreatePbuffer, { "glXCreatePbuffer", NULL } },
        { (PRFuncPtr*) &xCreateNewContext, { "glXCreateNewContext", NULL } },
        { (PRFuncPtr*) &xDestroyPbuffer, { "glXDestroyPbuffer", NULL } },
        { (PRFuncPtr*) &xGetVisualFromFBConfig, { "glXGetVisualFromFBConfig", NULL } },
        { (PRFuncPtr*) &xGetFBConfigAttrib, { "glXGetFBConfigAttrib", NULL } },
        { (PRFuncPtr*) &xSwapBuffers, { "glXSwapBuffers", NULL } },
        { (PRFuncPtr*) &xQueryServerString, { "glXQueryServerString", NULL } },
        { (PRFuncPtr*) &xCreatePixmap, { "glXCreatePixmap", NULL } },
        { (PRFuncPtr*) &xDestroyPixmap, { "glXDestroyPixmap", NULL } },
        { (PRFuncPtr*) &xGetClientString, { "glXGetClientString", NULL } },
        { (PRFuncPtr*) &xCreateContext, { "glXCreateContext", NULL } },
        { NULL, { NULL } }
    };

    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &symbols[0])) {
        NS_WARNING("Couldn't find required entry point in OpenGL shared library");
        return PR_FALSE;
    }

    const char *vendor = xQueryServerString(DefaultXDisplay(),
                                            DefaultScreen(DefaultXDisplay()),
                                            GLX_VENDOR);
    const char *serverVersionStr = xQueryServerString(DefaultXDisplay(),
                                                      DefaultScreen(DefaultXDisplay()),
                                                      GLX_VERSION);
    const char *clientVersionStr = xGetClientString(DefaultXDisplay(),
                                                    GLX_VERSION);


    int serverVersion = 0, clientVersion = 0;
    if (serverVersionStr &&
        strlen(serverVersionStr) >= 3 &&
        serverVersionStr[1] == '.')
    {
        serverVersion = (serverVersionStr[0] - '0') << 8 | (serverVersionStr[2] - '0');
    }

    if (clientVersionStr &&
        strlen(clientVersionStr) >= 3 &&
        clientVersionStr[1] == '.')
    {
        clientVersion = (clientVersionStr[0] - '0') << 8 | (clientVersionStr[2] - '0');
    }

    gGLXVersion = PR_MIN(clientVersion, serverVersion);

    if (gGLXVersion < 0x0103)
        return PR_FALSE;

    gIsATI = vendor && strstr(vendor, "ATI");
    gIsChromium = (vendor && strstr(vendor, "Chromium")) ||
        (serverVersion && strstr(serverVersionStr, "Chromium"));

    mInitialized = PR_TRUE;
    return PR_TRUE;
}
Beispiel #20
0
bool
GLLibraryEGL::EnsureInitialized()
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
      MOZ_CRASH("Tls init failed");
#endif

#ifdef XP_WIN
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }

#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(Terminate),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    // Do not warn about the failure to load this - see bug 1092191
    GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0], nullptr, nullptr,
                                 false);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "Couldn't find eglQueryStringImplementationANDROID");
#endif

    //Initialize client extensions
    InitExtensionsFromDisplay(EGL_NO_DISPLAY);

    GLLibraryLoader::PlatformLookupFunction lookupFunction =
        (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

#ifdef XP_WIN
    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_platform_angle_d3d);

            mSymbols.fGetPlatformDisplayEXT = nullptr;
        }
    }
#endif

    mEGLDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);

    const char* vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 ||
                   strstr(vendor, "Google Inc.") != 0))
    {
        mIsANGLE = true;
    }

    if (mIsANGLE) {
        EGLDisplay newDisplay = EGL_NO_DISPLAY;

        // D3D11 ANGLE only works with OMTC; there's a bug in the non-OMTC layer
        // manager, and it's pointless to try to fix it.  We also don't try
        // D3D11 ANGLE if the layer manager is prefering D3D9 (hrm, do we care?)
        if (gfxPrefs::LayersOffMainThreadCompositionEnabled() &&
            !gfxPrefs::LayersPreferD3D9())
        {
            if (gfxPrefs::WebGLANGLEForceD3D11()) {
                newDisplay = GetAndInitDisplay(*this,
                                               LOCAL_EGL_D3D11_ONLY_DISPLAY_ANGLE);
            } else if (gfxPrefs::WebGLANGLETryD3D11() && gfxPlatform::CanUseDirect3D11ANGLE()) {
                newDisplay = GetAndInitDisplay(*this,
                                               LOCAL_EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE);
            }
        }

        if (newDisplay != EGL_NO_DISPLAY) {
            DebugOnly<EGLBoolean> success = fTerminate(mEGLDisplay);
            MOZ_ASSERT(success == LOCAL_EGL_TRUE);

            mEGLDisplay = newDisplay;

            vendor = (char*)fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
        }
    }

    InitExtensionsFromDisplay(mEGLDisplay);

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    //XXX: use correct extension name
    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fSurfaceReleaseSyncANGLE, { "eglSurfaceReleaseSyncANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fSurfaceReleaseSyncANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    if (IsExtensionSupported(ANDROID_native_fence_sync)) {
        GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &nativeFenceSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(ANDROID_native_fence_sync);

            mSymbols.fDupNativeFenceFDANDROID = nullptr;
        }
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
NS_IMETHODIMP
nsNativeAppSupportUnix::Start(bool *aRetVal)
{
  NS_ASSERTION(gAppData, "gAppData must not be null.");

// The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService,
// from diffrent threads. This could lead to race conditions if the dbus is not
// initialized before making any other library calls.
#ifdef MOZ_ENABLE_DBUS
  dbus_threads_init_default();
#endif

#if (MOZ_WIDGET_GTK == 2)
  if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
      (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
    GtkWidget* versionErrDialog = gtk_message_dialog_new(NULL,
                     GtkDialogFlags(GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT),
                     GTK_MESSAGE_ERROR,
                     GTK_BUTTONS_OK,
                     UNSUPPORTED_GTK_MSG,
                     gtk_major_version,
                     gtk_minor_version,
                     MIN_GTK_MAJOR_VERSION,
                     MIN_GTK_MINOR_VERSION);
    gtk_dialog_run(GTK_DIALOG(versionErrDialog));
    gtk_widget_destroy(versionErrDialog);
    exit(0);
  }
#endif

#if (MOZ_PLATFORM_MAEMO == 5)
  /* zero state out. */
  memset(&m_hw_state, 0, sizeof(osso_hw_state_t));

  /* Initialize maemo application
     
     The initalization name will be of the form "Vendor.Name".
     If a Vendor isn't given, then we will just use "Name".
     
     Note that this value must match your X-Osso-Service name
     defined in your desktop file.  If it doesn't, the OSSO
     system will happily kill your process.
  */
  nsAutoCString applicationName;
  if (gAppData->vendor) {
      applicationName.Append(gAppData->vendor);
      applicationName.Append(".");
  }
  applicationName.Append(gAppData->name);
  ToLowerCase(applicationName);

  m_osso_context = osso_initialize(applicationName.get(), 
                                   gAppData->version ? gAppData->version : "1.0",
                                   true,
                                   nullptr);

  /* Check that initilialization was ok */
  if (m_osso_context == nullptr) {
      return NS_ERROR_FAILURE;
  }

  osso_hw_set_event_cb(m_osso_context, nullptr, OssoHardwareCallback, &m_hw_state);
  osso_hw_set_display_event_cb(m_osso_context, OssoDisplayCallback, m_osso_context);
  osso_rpc_set_default_cb_f(m_osso_context, OssoDbusCallback, nullptr);

  // Setup an MCE callback to monitor orientation
  DBusConnection *connnection = (DBusConnection*)osso_get_sys_dbus_connection(m_osso_context);
  dbus_bus_add_match(connnection, MCE_MATCH_RULE, nullptr);
  dbus_connection_add_filter(connnection, OssoModeControlCallback, nullptr, nullptr);
#endif

  *aRetVal = true;

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)

  PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0");
  if (!gnomeuiLib)
    return NS_OK;

  PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0");
  if (!gnomeLib) {
    PR_UnloadLibrary(gnomeuiLib);
    return NS_OK;
  }

  _gnome_program_init_fn gnome_program_init =
    (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init");
  _gnome_program_get_fn gnome_program_get =
    (_gnome_program_get_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_get"); 
 _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get");
  if (!gnome_program_init || !gnome_program_get || !libgnomeui_module_info_get) {
    PR_UnloadLibrary(gnomeuiLib);
    PR_UnloadLibrary(gnomeLib);
    return NS_OK;
  }

#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  // We will load gail, atk-bridge by ourself later
  // We can't run atk-bridge init here, because gail get the control
  // Set GNOME_ACCESSIBILITY to 0 can avoid this
  static const char *accEnv = "GNOME_ACCESSIBILITY";
  const char *accOldValue = getenv(accEnv);
  setenv(accEnv, "0", 1);
#endif

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  if (!gnome_program_get()) {
    gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), gArgc, gArgv, NULL);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  if (accOldValue) { 
    setenv(accEnv, accOldValue, 1);
  } else {
    unsetenv(accEnv);
  }
#endif

  // Careful! These libraries cannot be unloaded after this point because
  // gnome_program_init causes atexit handlers to be registered. Strange
  // crashes will occur if these libraries are unloaded.

  // TODO GTK3 - see Bug 694570 - Stop using libgnome and libgnomeui on Linux
#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command");

  _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");

  GnomeClient *client = gnome_master_client();
  g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), NULL);
  g_signal_connect(client, "die", G_CALLBACK(die_cb), NULL);

  // Set the correct/requested restart command in any case.

  // Is there a request to suppress default binary launcher?
  nsAutoCString path;
  char* argv1 = getenv("MOZ_APP_LAUNCHER");

  if(!argv1) {
    // Tell the desktop the command for restarting us so that we can be part of XSMP session restore
    NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
    nsCOMPtr<nsIFile> executablePath;
    nsresult rv;

    bool dummy;
    rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));

    if (NS_SUCCEEDED(rv)) {
      // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
      nsAutoCString leafName;
      rv = executablePath->GetNativeLeafName(leafName);
      if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
        leafName.SetLength(leafName.Length() - strlen("-bin"));
        executablePath->SetNativeLeafName(leafName);
      }

      executablePath->GetNativePath(path);
      argv1 = (char*)(path.get());
    }
  }

  if (argv1) {
    gnome_client_set_restart_command(client, 1, &argv1);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

  return NS_OK;
}
PRBool
WGLLibrary::EnsureInitialized()
{
    if (mInitialized)
        return PR_TRUE;

    if (!mOGLLibrary) {
        mOGLLibrary = PR_LoadLibrary("Opengl32.dll");
        if (!mOGLLibrary) {
            NS_WARNING("Couldn't load OpenGL DLL.");
            return PR_FALSE;
        }
    }

    LibrarySymbolLoader::SymLoadStruct earlySymbols[] = {
        { (PRFuncPtr*) &fCreateContext, { "wglCreateContext", NULL } },
        { (PRFuncPtr*) &fMakeCurrent, { "wglMakeCurrent", NULL } },
        { (PRFuncPtr*) &fGetProcAddress, { "wglGetProcAddress", NULL } },
        { (PRFuncPtr*) &fDeleteContext, { "wglDeleteContext", NULL } },
        { (PRFuncPtr*) &fGetCurrentContext, { "wglGetCurrentContext", NULL } },
        { (PRFuncPtr*) &fGetCurrentDC, { "wglGetCurrentDC", NULL } },
        { (PRFuncPtr*) &fShareLists, { "wglShareLists", NULL } },
        { NULL, { NULL } }
    };

    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in OpenGL DLL (early init)");
        return PR_FALSE;
    }

    // This is ridiculous -- we have to actually create a context to
    // get the OpenGL ICD to load.
    gSharedWindow = CreateDummyWindow(&gSharedWindowDC);
    NS_ENSURE_TRUE(gSharedWindow, PR_FALSE);

    // create rendering context
    gSharedWindowGLContext = fCreateContext(gSharedWindowDC);
    NS_ENSURE_TRUE(gSharedWindowGLContext, PR_FALSE);

    HGLRC curCtx = fGetCurrentContext();
    HDC curDC = fGetCurrentDC();

    if (!fMakeCurrent((HDC)gSharedWindowDC, (HGLRC)gSharedWindowGLContext)) {
        NS_WARNING("wglMakeCurrent failed");
        return PR_FALSE;
    }

    // Now we can grab all the other symbols that we couldn't without having
    // a context current.

    LibrarySymbolLoader::SymLoadStruct pbufferSymbols[] = {
        { (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", NULL } },
        { (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", NULL } },
        { (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", NULL } },
        { (PRFuncPtr*) &fBindTexImage, { "wglBindTexImageARB", "wglBindTexImageEXT", NULL } },
        { (PRFuncPtr*) &fReleaseTexImage, { "wglReleaseTexImageARB", "wglReleaseTexImageEXT", NULL } },
        { NULL, { NULL } }
    };

    LibrarySymbolLoader::SymLoadStruct pixFmtSymbols[] = {
        { (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", NULL } },
        { (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", NULL } },
        { NULL, { NULL } }
    };

    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
         (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
    {
        // this isn't an error, just means that pbuffers aren't supported
        fCreatePbuffer = nsnull;
    }

    if (!LibrarySymbolLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
         (LibrarySymbolLoader::PlatformLookupFunction)fGetProcAddress))
    {
        // this isn't an error, just means that we don't have the pixel format extension
        fChoosePixelFormat = nsnull;
    }

    // reset back to the previous context, just in case
    fMakeCurrent(curDC, curCtx);

    mInitialized = PR_TRUE;

    // Call this to create the global GLContext instance,
    // and to check for errors.  Note that this must happen /after/
    // setting mInitialized to TRUE, or an infinite loop results.
    if (GLContextProviderWGL::GetGlobalContext() == nsnull) {
        mInitialized = PR_FALSE;
        return PR_FALSE;
    }

    return PR_TRUE;
}
Beispiel #23
0
bool
GLLibraryEGL::EnsureInitialized()
{
    nsresult rv;

    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef XP_WIN
    if (!mEGLLibrary) {
        // On Windows, the GLESv2 and EGL libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll.

        nsCOMPtr<nsIFile> libraryFile;

        nsCOMPtr<nsIProperties> dirService =
            do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
        if (!dirService)
            return false;

        rv = dirService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile),
                             getter_AddRefs(libraryFile));
        if (NS_FAILED(rv))
            return false;

        libraryFile->Append(NS_LITERAL_STRING("libGLESv2.dll"));
        PRLibrary* glesv2lib = nsnull;

        libraryFile->Load(&glesv2lib);

        // Intentionally leak glesv2lib
    
        libraryFile->SetLeafName(NS_LITERAL_STRING("libEGL.dll"));
        rv = libraryFile->Load(&mEGLLibrary);
        if (NS_FAILED(rv)) {
            NS_WARNING("Couldn't load libEGL.dll, canvas3d will be disabled.");
            return false;
        }
    }
#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { NULL, { NULL } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

#if defined(MOZ_X11) && defined(MOZ_EGL_XRENDER_COMPOSITE)
    mEGLDisplay = fGetDisplay((EGLNativeDisplayType) gdk_x11_get_default_xdisplay());
#else
    mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
#endif
    if (!fInitialize(mEGLDisplay, NULL, NULL))
        return false;

    const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
        mIsANGLE = true;
    }
    
    const char *extensions = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_EXTENSIONS);
    if (!extensions)
        extensions = "";

    printf_stderr("Extensions: %s 0x%02x\n", extensions, extensions[0]);
    printf_stderr("Extensions length: %d\n", strlen(extensions));

    // note the extra space -- this ugliness tries to match
    // EGL_KHR_image in the middle of the string, or right at the
    // end.  It's a prefix for other extensions, so we have to do
    // this...
    bool hasKHRImage = false;
    if (strstr(extensions, "EGL_KHR_image ") ||
        (strlen(extensions) >= strlen("EGL_KHR_image") &&
         strcmp(extensions+(strlen(extensions)-strlen("EGL_KHR_image")), "EGL_KHR_image")))
    {
        hasKHRImage = true;
    }

    if (strstr(extensions, "EGL_KHR_image_base")) {
        mHave_EGL_KHR_image_base = true;
    }
        
    if (strstr(extensions, "EGL_KHR_image_pixmap")) {
        mHave_EGL_KHR_image_pixmap = true;
        
    }

    if (strstr(extensions, "EGL_KHR_gl_texture_2D_image")) {
        mHave_EGL_KHR_gl_texture_2D_image = true;
    }

    if (strstr(extensions, "EGL_KHR_lock_surface")) {
        mHave_EGL_KHR_lock_surface = true;
    }

    if (hasKHRImage) {
        GLLibraryLoader::SymLoadStruct khrSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImageKHR, { "eglCreateImageKHR", NULL } },
            { (PRFuncPtr*) &mSymbols.fDestroyImageKHR, { "eglDestroyImageKHR", NULL } },
            { (PRFuncPtr*) &mSymbols.fImageTargetTexture2DOES, { "glEGLImageTargetTexture2DOES", NULL } },
            { NULL, { NULL } }
        };

        GLLibraryLoader::LoadSymbols(mEGLLibrary, &khrSymbols[0],
                                         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
    }

    if (mHave_EGL_KHR_lock_surface) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurfaceKHR, { "eglLockSurfaceKHR", NULL } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurfaceKHR, { "eglUnlockSurfaceKHR", NULL } },
            { NULL, { NULL } }
        };

        GLLibraryLoader::LoadSymbols(mEGLLibrary, &lockSymbols[0],
                                         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
        if (!mSymbols.fLockSurfaceKHR) {
            mHave_EGL_KHR_lock_surface = false;
        }
    }

    if (!mSymbols.fCreateImageKHR) {
        mHave_EGL_KHR_image_base = false;
        mHave_EGL_KHR_image_pixmap = false;
        mHave_EGL_KHR_gl_texture_2D_image = false;
    }

    if (!mSymbols.fImageTargetTexture2DOES) {
        mHave_EGL_KHR_gl_texture_2D_image = false;
    }

    if (strstr(extensions, "EGL_ANGLE_surface_d3d_texture_2d_share_handle")) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", NULL } },
            { NULL, { NULL } }
        };

        GLLibraryLoader::LoadSymbols(mEGLLibrary, &d3dSymbols[0],
                                         (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress);
        if (mSymbols.fQuerySurfacePointerANGLE) {
            mHave_EGL_ANGLE_surface_d3d_texture_2d_share_handle = true;
        }
    }

    if (strstr(extensions, "EGL_EXT_create_context_robustness")) {
        mHasRobustness = true;
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
Beispiel #24
0
// Load a plugin dll.  "pluginType" is a handle to a plugin management data
// structure created during FE_RegisterPlugins().  "pNavigatorFuncs" is
// a table of entry points into Navigator, which are the services provided
// by Navigator to plugins, such as requestread() and GetUrl().  These entry
// points are stored and called by the plugin when services are needed.
// The return val is a table of functions which are entry points to the
// newly loaded plugin, such as NewStream() and Write().
NPPluginFuncs* FE_LoadPlugin(void* pluginType, NPNetscapeFuncs* pNavigatorFuncs, np_handle* handle)
{
    if(pluginType == NULL)
        return NULL;

    NPPMgtBlk* pNPMgtBlock = (NPPMgtBlk*)pluginType;

    CString csPluginDir;
    wfe_GetPluginsDirectory(csPluginDir);

    LPSTR pPathSave = NULL;   // storage for one dir spec

    wfe_PushPath(&pPathSave);  // save the current drive and dir

    // change the default dir so that implib'd plugins won't fail
    if(_chdir(csPluginDir) != 0) {
        wfe_PopPath(pPathSave);  // restore the path
        return NULL;
    }

    // must change the drive as well as the dir path
    if(isalpha(csPluginDir[0]) && csPluginDir[1] == ':') {
        if(_chdrive(wfe_MapAsciiToDriveNum(csPluginDir[0])) != 0) {
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }
    }

    pNPMgtBlock->pLibrary = PR_LoadLibrary(pNPMgtBlock->pPluginFilename);

    // the cross platform code should take care of the 16/32 bit issues
    if(pNPMgtBlock->pLibrary == NULL)
        return NULL;
    
    NP_CREATEPLUGIN npCreatePlugin =
#ifndef NSPR20
        (NP_CREATEPLUGIN)PR_FindSymbol("NP_CreatePlugin", pNPMgtBlock->pLibrary);
#else
        (NP_CREATEPLUGIN)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_CreatePlugin");
#endif
    if (npCreatePlugin != NULL) {
        if (thePluginManager == NULL) {
            static NS_DEFINE_IID(kIPluginManagerIID, NP_IPLUGINMANAGER_IID);
            if (nsPluginManager::Create(NULL, kIPluginManagerIID, (void**)&thePluginManager) != NS_OK)
                return NULL;
        }
        NPIPlugin* plugin = NULL;
        NPPluginError err = npCreatePlugin(thePluginManager, &plugin);
        handle->userPlugin = plugin;
        if (err == NPPluginError_NoError && plugin != NULL) {
            pNPMgtBlock->pPluginFuncs = (NPPluginFuncs*)-1;   // something to say it's loaded, but != 0
        }
    }
    else {

        NP_GETENTRYPOINTS getentrypoints =
#ifndef NSPR20
            (NP_GETENTRYPOINTS)PR_FindSymbol("NP_GetEntryPoints", pNPMgtBlock->pLibrary);
#else
            (NP_GETENTRYPOINTS)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_GetEntryPoints");
#endif
        if(getentrypoints == NULL)
        {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }
    
        if(pNPMgtBlock->pPluginFuncs == NULL)
        {
            pNPMgtBlock->pPluginFuncs = new NPPluginFuncs;
            pNPMgtBlock->pPluginFuncs->size = sizeof NPPluginFuncs;
            pNPMgtBlock->pPluginFuncs->javaClass = NULL;
            if(pNPMgtBlock->pPluginFuncs == NULL)   // fatal, can't continue
            {
                PR_UnloadLibrary(pNPMgtBlock->pLibrary);
                wfe_PopPath(pPathSave);  // restore the path
                return NULL;
            }
        }

        if(getentrypoints(pNPMgtBlock->pPluginFuncs) != NPERR_NO_ERROR)
        {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }

        // if the plugin's major ver level is lower than the Navigator's,
        // then they are incompatible, and should return an error
        if(HIBYTE(pNPMgtBlock->pPluginFuncs->version) < NP_VERSION_MAJOR)
        {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }

        NP_PLUGININIT npinit = NULL;

        // if this DLL is not already loaded, call its initialization entry point
        if(pNPMgtBlock->uRefCount == 0) {
            // the NP_Initialize entry point was misnamed as NP_PluginInit, early
            // in plugin project development.  Its correct name is documented
            // now, and new developers expect it to work.  However, I don't want
            // to  break the plugins already in the field, so I'll accept either
            // name
            npinit =
#ifndef NSPR20
                (NP_PLUGININIT)PR_FindSymbol("NP_Initialize", pNPMgtBlock->pLibrary);
#else
                (NP_PLUGININIT)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_Initialize");
#endif
            if(!npinit) {
                npinit =
#ifndef NSPR20
                    (NP_PLUGININIT)PR_FindSymbol("NP_PluginInit", pNPMgtBlock->pLibrary);
#else
                    (NP_PLUGININIT)PR_FindSymbol(pNPMgtBlock->pLibrary, "NP_PluginInit");
#endif
            }
        }

        if(npinit == NULL) {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }

        if (npinit(pNavigatorFuncs) != NPERR_NO_ERROR) {
            PR_UnloadLibrary(pNPMgtBlock->pLibrary);
            delete pNPMgtBlock->pPluginFuncs;
            pNPMgtBlock->pPluginFuncs = NULL;
            wfe_PopPath(pPathSave);  // restore the path
            return NULL;
        }
    }
    
    pNPMgtBlock->uRefCount++;   // all is well, remember it was loaded
    
    // can't pop the path until plugins have been completely loaded/init'd
    wfe_PopPath(pPathSave);  // restore the path
    return pNPMgtBlock->pPluginFuncs;
}
NS_IMETHODIMP
nsNativeAppSupportUnix::Start(bool *aRetVal)
{
  NS_ASSERTION(gAppData, "gAppData must not be null.");

// The dbus library is used by both nsWifiScannerDBus and BluetoothDBusService,
// from diffrent threads. This could lead to race conditions if the dbus is not
// initialized before making any other library calls.
#ifdef MOZ_ENABLE_DBUS
  dbus_threads_init_default();
#endif

#if (MOZ_WIDGET_GTK == 2)
  if (gtk_major_version < MIN_GTK_MAJOR_VERSION ||
      (gtk_major_version == MIN_GTK_MAJOR_VERSION && gtk_minor_version < MIN_GTK_MINOR_VERSION)) {
    GtkWidget* versionErrDialog = gtk_message_dialog_new(NULL,
                     GtkDialogFlags(GTK_DIALOG_MODAL |
                                    GTK_DIALOG_DESTROY_WITH_PARENT),
                     GTK_MESSAGE_ERROR,
                     GTK_BUTTONS_OK,
                     UNSUPPORTED_GTK_MSG,
                     gtk_major_version,
                     gtk_minor_version,
                     MIN_GTK_MAJOR_VERSION,
                     MIN_GTK_MINOR_VERSION);
    gtk_dialog_run(GTK_DIALOG(versionErrDialog));
    gtk_widget_destroy(versionErrDialog);
    exit(0);
  }
#endif

  *aRetVal = true;

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)

  PRLibrary *gnomeuiLib = PR_LoadLibrary("libgnomeui-2.so.0");
  if (!gnomeuiLib)
    return NS_OK;

  PRLibrary *gnomeLib = PR_LoadLibrary("libgnome-2.so.0");
  if (!gnomeLib) {
    PR_UnloadLibrary(gnomeuiLib);
    return NS_OK;
  }

  _gnome_program_init_fn gnome_program_init =
    (_gnome_program_init_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_init");
  _gnome_program_get_fn gnome_program_get =
    (_gnome_program_get_fn)PR_FindFunctionSymbol(gnomeLib, "gnome_program_get"); 
 _libgnomeui_module_info_get_fn libgnomeui_module_info_get = (_libgnomeui_module_info_get_fn)PR_FindFunctionSymbol(gnomeuiLib, "libgnomeui_module_info_get");
  if (!gnome_program_init || !gnome_program_get || !libgnomeui_module_info_get) {
    PR_UnloadLibrary(gnomeuiLib);
    PR_UnloadLibrary(gnomeLib);
    return NS_OK;
  }

#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  // We will load gail, atk-bridge by ourself later
  // We can't run atk-bridge init here, because gail get the control
  // Set GNOME_ACCESSIBILITY to 0 can avoid this
  static const char *accEnv = "GNOME_ACCESSIBILITY";
  const char *accOldValue = getenv(accEnv);
  setenv(accEnv, "0", 1);
#endif

#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  if (!gnome_program_get()) {
    gnome_program_init("Gecko", "1.0", libgnomeui_module_info_get(), gArgc, gArgv, NULL);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

#ifdef ACCESSIBILITY
  if (accOldValue) { 
    setenv(accEnv, accOldValue, 1);
  } else {
    unsetenv(accEnv);
  }
#endif

  // Careful! These libraries cannot be unloaded after this point because
  // gnome_program_init causes atexit handlers to be registered. Strange
  // crashes will occur if these libraries are unloaded.

  // TODO GTK3 - see Bug 694570 - Stop using libgnome and libgnomeui on Linux
#if defined(MOZ_X11) && (MOZ_WIDGET_GTK == 2)
  gnome_client_set_restart_command = (_gnome_client_set_restart_command_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_client_set_restart_command");

  _gnome_master_client_fn gnome_master_client = (_gnome_master_client_fn)
    PR_FindFunctionSymbol(gnomeuiLib, "gnome_master_client");

  GnomeClient *client = gnome_master_client();
  g_signal_connect(client, "save-yourself", G_CALLBACK(save_yourself_cb), NULL);
  g_signal_connect(client, "die", G_CALLBACK(die_cb), NULL);

  // Set the correct/requested restart command in any case.

  // Is there a request to suppress default binary launcher?
  nsAutoCString path;
  char* argv1 = getenv("MOZ_APP_LAUNCHER");

  if(!argv1) {
    // Tell the desktop the command for restarting us so that we can be part of XSMP session restore
    NS_ASSERTION(gDirServiceProvider, "gDirServiceProvider is NULL! This shouldn't happen!");
    nsCOMPtr<nsIFile> executablePath;
    nsresult rv;

    bool dummy;
    rv = gDirServiceProvider->GetFile(XRE_EXECUTABLE_FILE, &dummy, getter_AddRefs(executablePath));

    if (NS_SUCCEEDED(rv)) {
      // Strip off the -bin suffix to get the shell script we should run; this is what Breakpad does
      nsAutoCString leafName;
      rv = executablePath->GetNativeLeafName(leafName);
      if (NS_SUCCEEDED(rv) && StringEndsWith(leafName, NS_LITERAL_CSTRING("-bin"))) {
        leafName.SetLength(leafName.Length() - strlen("-bin"));
        executablePath->SetNativeLeafName(leafName);
      }

      executablePath->GetNativePath(path);
      argv1 = (char*)(path.get());
    }
  }

  if (argv1) {
    gnome_client_set_restart_command(client, 1, &argv1);
  }
#endif /* MOZ_X11 && (MOZ_WIDGET_GTK == 2) */

  return NS_OK;
}
Beispiel #26
0
bool
GLLibraryEGL::EnsureInitialized()
{
    if (mInitialized) {
        return true;
    }

#ifdef XP_WIN
#ifdef MOZ_WEBGL
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

#ifndef MOZ_D3DCOMPILER_DLL
#error MOZ_D3DCOMPILER_DLL should have been defined by the Makefile
#endif
        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_DLL)));
        // intentionally leak the D3DCOMPILER_DLL library

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));
        // intentionally leak the libGLESv2.dll library

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }
#endif // MOZ_WEBGL
#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, NULL } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { NULL, { NULL } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
    if (!fInitialize(mEGLDisplay, NULL, NULL))
        return false;

    const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
        mIsANGLE = true;
    }
    
    InitExtensions();

    GLLibraryLoader::PlatformLookupFunction lookupFunction =
            (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    mInitialized = true;
    return true;
}
bool
WGLLibrary::EnsureInitialized(bool aUseMesaLlvmPipe)
{
    if (mInitialized)
        return true;
    
    mozilla::ScopedGfxFeatureReporter reporter("WGL", aUseMesaLlvmPipe);

    const char* libGLFilename = aUseMesaLlvmPipe 
                                ? "mesallvmpipe.dll" 
                                : "Opengl32.dll";
    if (!mOGLLibrary) {
        mOGLLibrary = PR_LoadLibrary(libGLFilename);
        if (!mOGLLibrary) {
            NS_WARNING("Couldn't load OpenGL library.");
            return false;
        }
    }

    mUseDoubleBufferedWindows = PR_GetEnv("MOZ_WGL_DB") != nullptr;

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        { (PRFuncPtr*) &fCreateContext, { "wglCreateContext", NULL } },
        { (PRFuncPtr*) &fMakeCurrent, { "wglMakeCurrent", NULL } },
        { (PRFuncPtr*) &fGetProcAddress, { "wglGetProcAddress", NULL } },
        { (PRFuncPtr*) &fDeleteContext, { "wglDeleteContext", NULL } },
        { (PRFuncPtr*) &fGetCurrentContext, { "wglGetCurrentContext", NULL } },
        { (PRFuncPtr*) &fGetCurrentDC, { "wglGetCurrentDC", NULL } },
        { (PRFuncPtr*) &fShareLists, { "wglShareLists", NULL } },
        { NULL, { NULL } }
    };

    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in OpenGL DLL (early init)");
        return false;
    }

    // This is ridiculous -- we have to actually create a context to
    // get the OpenGL ICD to load.
    mWindow = CreateDummyWindow(&mWindowDC);
    NS_ENSURE_TRUE(mWindow, false);

    // create rendering context
    mWindowGLContext = fCreateContext(mWindowDC);
    NS_ENSURE_TRUE(mWindowGLContext, false);

    HGLRC curCtx = fGetCurrentContext();
    HDC curDC = fGetCurrentDC();

    if (!fMakeCurrent((HDC)mWindowDC, (HGLRC)mWindowGLContext)) {
        NS_WARNING("wglMakeCurrent failed");
        return false;
    }

    // Now we can grab all the other symbols that we couldn't without having
    // a context current.

    GLLibraryLoader::SymLoadStruct pbufferSymbols[] = {
        { (PRFuncPtr*) &fCreatePbuffer, { "wglCreatePbufferARB", "wglCreatePbufferEXT", NULL } },
        { (PRFuncPtr*) &fDestroyPbuffer, { "wglDestroyPbufferARB", "wglDestroyPbufferEXT", NULL } },
        { (PRFuncPtr*) &fGetPbufferDC, { "wglGetPbufferDCARB", "wglGetPbufferDCEXT", NULL } },
        { (PRFuncPtr*) &fBindTexImage, { "wglBindTexImageARB", "wglBindTexImageEXT", NULL } },
        { (PRFuncPtr*) &fReleaseTexImage, { "wglReleaseTexImageARB", "wglReleaseTexImageEXT", NULL } },
        { NULL, { NULL } }
    };

    GLLibraryLoader::SymLoadStruct pixFmtSymbols[] = {
        { (PRFuncPtr*) &fChoosePixelFormat, { "wglChoosePixelFormatARB", "wglChoosePixelFormatEXT", NULL } },
        { (PRFuncPtr*) &fGetPixelFormatAttribiv, { "wglGetPixelFormatAttribivARB", "wglGetPixelFormatAttribivEXT", NULL } },
        { NULL, { NULL } }
    };

    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pbufferSymbols[0],
         (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
    {
        // this isn't an error, just means that pbuffers aren't supported
        fCreatePbuffer = nullptr;
    }

    if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, &pixFmtSymbols[0],
         (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress))
    {
        // this isn't an error, just means that we don't have the pixel format extension
        fChoosePixelFormat = nullptr;
    }

    GLLibraryLoader::SymLoadStruct extensionsSymbols[] = {
        { (PRFuncPtr *) &fGetExtensionsString, { "wglGetExtensionsStringARB", NULL} },
        { NULL, { NULL } }
    };

    GLLibraryLoader::SymLoadStruct robustnessSymbols[] = {
        { (PRFuncPtr *) &fCreateContextAttribs, { "wglCreateContextAttribsARB", NULL} },
        { NULL, { NULL } }
    };

    if (GLLibraryLoader::LoadSymbols(mOGLLibrary, &extensionsSymbols[0],
        (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress)) {
        const char *wglExts = fGetExtensionsString(mWindowDC);
        if (wglExts && HasExtension(wglExts, "WGL_ARB_create_context")) {
            GLLibraryLoader::LoadSymbols(mOGLLibrary, &robustnessSymbols[0],
            (GLLibraryLoader::PlatformLookupFunction)fGetProcAddress);
            if (HasExtension(wglExts, "WGL_ARB_create_context_robustness")) {
                mHasRobustness = true;
            }
        }
    }

    // reset back to the previous context, just in case
    fMakeCurrent(curDC, curCtx);

    if (mHasRobustness) {
        fDeleteContext(mWindowGLContext);

        int attribs[] = {
            LOCAL_WGL_CONTEXT_FLAGS_ARB, LOCAL_WGL_CONTEXT_ROBUST_ACCESS_BIT_ARB,
            LOCAL_WGL_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB, LOCAL_WGL_LOSE_CONTEXT_ON_RESET_ARB,
            0
        };

        mWindowGLContext = fCreateContextAttribs(mWindowDC, NULL, attribs);
        if (!mWindowGLContext) {
            mHasRobustness = false;
            mWindowGLContext = fCreateContext(mWindowDC);
        }
    }

    mInitialized = true;

    GLContext::ContextFlags flag = GLContext::ContextFlagsNone;
    if (aUseMesaLlvmPipe) {
      mLibType = WGLLibrary::MESA_LLVMPIPE_LIB;
      flag = GLContext::ContextFlagsMesaLLVMPipe;
    }

    // Call this to create the global GLContext instance,
    // and to check for errors.  Note that this must happen /after/
    // setting mInitialized to TRUE, or an infinite loop results.
    if (GLContextProviderWGL::GetGlobalContext(flag) == nullptr) {
        mInitialized = false;
        return false;
    }

    reporter.SetSuccessful();
    return true;
}
Beispiel #28
0
/* static */
bool WebCL_LibCL::load (char const* aLibName, WebCL_LibCL** aInstanceOut,
                        nsCString* aErrorMessageOut)
{
  D_METHOD_START;

  if (!aLibName)
  {
    D_LOG (LOG_LEVEL_ERROR, "Invalid arguments: aLibName = NULL.");
    if (aErrorMessageOut)
      *aErrorMessageOut = "Invalid library name: NULL";
    return false;
  }

  // Front strip lib name
  size_t libPathLen = strlen (aLibName);
  char const* cleanedLibName = aLibName;
  while (cleanedLibName < aLibName + libPathLen && isspace(*cleanedLibName))
    ++cleanedLibName;

  if (cleanedLibName[0] == '\0')
  {
    // Empty name now allowed here, handle default library on a higher level
    D_LOG (LOG_LEVEL_ERROR, "Invalid arguments: no library name given.");
    if (aErrorMessageOut)
      *aErrorMessageOut = "Invalid library name: \"\"";
    return false;
  }

  char* systemName = PR_GetLibraryName (NULL, cleanedLibName);
  D_LOG (LOG_LEVEL_DEBUG, "system name for library %s: %s", cleanedLibName, systemName);

  nsCOMPtr<WebCL_LibCL> instance (new (std::nothrow) WebCL_LibCL);
  instance->m_libName = strdup (systemName);

  PRLibrary* libHndl = PR_LoadLibrary (systemName);
  PR_FreeLibraryName (systemName);

  char* errText = 0;

  if (!libHndl)
  {
    // Perhaps PR_GetLibraryName failed?
    errText = getPRErrorText ();
    D_LOG (LOG_LEVEL_ERROR, "Failed to load library by system name %s: %s",
           instance->m_libName, errText);
    D_LOG (LOG_LEVEL_DEBUG, " (prerr: %d oserr: %d)", PR_GetError(), PR_GetOSError());
    PR_FREEIF (errText);
    errText = 0;

    // TODO: check if this is even sane?
    libHndl = PR_LoadLibrary (cleanedLibName);
    if (!libHndl)
    {
      // Failed to load the library.
      errText = getPRErrorText ();
      D_LOG (LOG_LEVEL_ERROR, "Failed to load library %s: %s", cleanedLibName, errText);
      D_LOG (LOG_LEVEL_DEBUG, "  (prerr: %d oserr: %d)", PR_GetError(), PR_GetOSError());
      if (aErrorMessageOut)
        *aErrorMessageOut = errText;

      PR_FREEIF (errText);

      return false;
    }

    instance->m_libName = strdup (cleanedLibName);
  }

  instance->m_libHandle = libHndl;
  if (!loadCLLibrary (instance, libHndl))
  {
    D_LOG (LOG_LEVEL_ERROR, "Failed to load library %s: required symbols missing.", instance->m_libName);
    if (aErrorMessageOut)
      *aErrorMessageOut = "Required symbols not found.";

    return false;
  }

  if (aInstanceOut)
  {
    NS_ADDREF (*aInstanceOut = instance);
  }

  return true;
}
Beispiel #29
0
bool
GLLibraryEGL::EnsureInitialized(bool forceAccel, nsACString* const out_failureId)
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
      MOZ_CRASH("GFX: Tls init failed");
#endif

#ifdef XP_WIN
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }

#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(Terminate),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    // Do not warn about the failure to load this - see bug 1092191
    Unused << GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0],
                                           nullptr, nullptr, false);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "GFX: Couldn't find eglQueryStringImplementationANDROID");
#endif

    InitClientExtensions();

    const auto lookupFunction =
        (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

    // Client exts are ready. (But not display exts!)
    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*)&mSymbols.fGetPlatformDisplayEXT, { "eglGetPlatformDisplayEXT", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_platform_angle_d3d without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_platform_angle_d3d);

            mSymbols.fGetPlatformDisplayEXT = nullptr;
        }
    }

    // Check the ANGLE support the system has
    nsCOMPtr<nsIGfxInfo> gfxInfo = do_GetService("@mozilla.org/gfx/info;1");
    mIsANGLE = IsExtensionSupported(ANGLE_platform_angle);

    EGLDisplay chosenDisplay = nullptr;

    if (IsExtensionSupported(ANGLE_platform_angle_d3d)) {
        bool accelAngleSupport = IsAccelAngleSupported(gfxInfo, out_failureId);
        bool shouldTryAccel = forceAccel || accelAngleSupport;
        bool shouldTryWARP = !forceAccel; // Only if ANGLE not supported or fails

        // If WARP preferred, will override ANGLE support
        if (gfxPrefs::WebGLANGLEForceWARP()) {
            shouldTryWARP = true;
            shouldTryAccel = false;
        }

        // Hardware accelerated ANGLE path (supported or force accel)
        if (shouldTryAccel) {
            chosenDisplay = GetAndInitDisplayForAccelANGLE(*this);
        }

        // Fallback to a WARP display if ANGLE fails, or if WARP is forced
        if (!chosenDisplay && shouldTryWARP) {
            chosenDisplay = GetAndInitWARPDisplay(*this, EGL_DEFAULT_DISPLAY);
            if (!chosenDisplay) {
                if (out_failureId->IsEmpty()) {
                    *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_WARP_FALLBACK");
                }
                NS_ERROR("Fallback WARP context failed to initialize.");
                return false;
            }
            mIsWARP = true;
        }
    } else {
        chosenDisplay = GetAndInitDisplay(*this, EGL_DEFAULT_DISPLAY);
    }

    if (!chosenDisplay) {
        if (out_failureId->IsEmpty()) {
            *out_failureId = NS_LITERAL_CSTRING("FEATURE_FAILURE_NO_DISPLAY");
        }
        NS_WARNING("Failed to initialize a display.");
        return false;
    }
    mEGLDisplay = chosenDisplay;

    InitDisplayExtensions();

    ////////////////////////////////////
    // Alright, load display exts.

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    if (IsExtensionSupported(ANDROID_native_fence_sync)) {
        GLLibraryLoader::SymLoadStruct nativeFenceSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fDupNativeFenceFDANDROID, { "eglDupNativeFenceFDANDROID", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &nativeFenceSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANDROID_native_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(ANDROID_native_fence_sync);

            mSymbols.fDupNativeFenceFDANDROID = nullptr;
        }
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}
Beispiel #30
0
bool
GLLibraryEGL::EnsureInitialized()
{
    if (mInitialized) {
        return true;
    }

    mozilla::ScopedGfxFeatureReporter reporter("EGL");

#ifdef MOZ_B2G
    if (!sCurrentContext.init())
	    MOZ_CRASH("Tls init failed");
#endif

#ifdef XP_WIN
#ifdef MOZ_WEBGL
    if (!mEGLLibrary) {
        // On Windows, the GLESv2, EGL and DXSDK libraries are shipped with libxul and
        // we should look for them there. We have to load the libs in this
        // order, because libEGL.dll depends on libGLESv2.dll which depends on the DXSDK
        // libraries. This matters especially for WebRT apps which are in a different directory.
        // See bug 760323 and bug 749459

        // Also note that we intentionally leak the libs we load.

        do {
            // Windows 8.1 has d3dcompiler_47.dll in the system directory.
            // Try it first. Note that _46 will never be in the system
            // directory and we ship with at least _43. So there is no point
            // trying _46 and _43 in the system directory.

            if (LoadLibrarySystem32(L"d3dcompiler_47.dll"))
                break;

#ifdef MOZ_D3DCOMPILER_VISTA_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_VISTA_DLL))))
                break;
#endif

#ifdef MOZ_D3DCOMPILER_XP_DLL
            if (LoadLibraryForEGLOnWindows(NS_LITERAL_STRING(NS_STRINGIFY(MOZ_D3DCOMPILER_XP_DLL))))
                break;
#endif

            MOZ_ASSERT(false, "d3dcompiler DLL loading failed.");
        } while (false);

        LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libGLESv2.dll"));

        mEGLLibrary = LoadLibraryForEGLOnWindows(NS_LITERAL_STRING("libEGL.dll"));

        if (!mEGLLibrary)
            return false;
    }
#endif // MOZ_WEBGL
#else // !Windows

    // On non-Windows (Android) we use system copies of libEGL. We look for
    // the APITrace lib, libEGL.so, and libEGL.so.1 in that order.

#if defined(ANDROID)
    if (!mEGLLibrary)
        mEGLLibrary = LoadApitraceLibrary();
#endif

    if (!mEGLLibrary) {
        printf_stderr("Attempting load of libEGL.so\n");
        mEGLLibrary = PR_LoadLibrary("libEGL.so");
    }
#if defined(XP_UNIX)
    if (!mEGLLibrary) {
        mEGLLibrary = PR_LoadLibrary("libEGL.so.1");
    }
#endif

    if (!mEGLLibrary) {
        NS_WARNING("Couldn't load EGL LIB.");
        return false;
    }

#endif // !Windows

#define SYMBOL(name) \
{ (PRFuncPtr*) &mSymbols.f##name, { "egl" #name, nullptr } }

    GLLibraryLoader::SymLoadStruct earlySymbols[] = {
        SYMBOL(GetDisplay),
        SYMBOL(GetCurrentSurface),
        SYMBOL(GetCurrentContext),
        SYMBOL(MakeCurrent),
        SYMBOL(DestroyContext),
        SYMBOL(CreateContext),
        SYMBOL(DestroySurface),
        SYMBOL(CreateWindowSurface),
        SYMBOL(CreatePbufferSurface),
        SYMBOL(CreatePixmapSurface),
        SYMBOL(BindAPI),
        SYMBOL(Initialize),
        SYMBOL(ChooseConfig),
        SYMBOL(GetError),
        SYMBOL(GetConfigs),
        SYMBOL(GetConfigAttrib),
        SYMBOL(WaitNative),
        SYMBOL(GetProcAddress),
        SYMBOL(SwapBuffers),
        SYMBOL(CopyBuffers),
        SYMBOL(QueryString),
        SYMBOL(QueryContext),
        SYMBOL(BindTexImage),
        SYMBOL(ReleaseTexImage),
        SYMBOL(QuerySurface),
        { nullptr, { nullptr } }
    };

    if (!GLLibraryLoader::LoadSymbols(mEGLLibrary, &earlySymbols[0])) {
        NS_WARNING("Couldn't find required entry points in EGL library (early init)");
        return false;
    }

    GLLibraryLoader::SymLoadStruct optionalSymbols[] = {
        // On Android 4.3 and up, certain features like ANDROID_native_fence_sync
        // can only be queried by using a special eglQueryString.
        { (PRFuncPtr*) &mSymbols.fQueryStringImplementationANDROID,
          { "_Z35eglQueryStringImplementationANDROIDPvi", nullptr } },
        { nullptr, { nullptr } }
    };

    GLLibraryLoader::LoadSymbols(mEGLLibrary, &optionalSymbols[0]);

#if defined(MOZ_WIDGET_GONK) && ANDROID_VERSION >= 18
    MOZ_RELEASE_ASSERT(mSymbols.fQueryStringImplementationANDROID,
                       "Couldn't find eglQueryStringImplementationANDROID");
#endif

    mEGLDisplay = fGetDisplay(EGL_DEFAULT_DISPLAY);
    if (!fInitialize(mEGLDisplay, nullptr, nullptr))
        return false;

    const char *vendor = (const char*) fQueryString(mEGLDisplay, LOCAL_EGL_VENDOR);
    if (vendor && (strstr(vendor, "TransGaming") != 0 || strstr(vendor, "Google Inc.") != 0)) {
        mIsANGLE = true;
    }

    InitExtensions();

    GLLibraryLoader::PlatformLookupFunction lookupFunction =
            (GLLibraryLoader::PlatformLookupFunction)mSymbols.fGetProcAddress;

    if (IsExtensionSupported(KHR_lock_surface)) {
        GLLibraryLoader::SymLoadStruct lockSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fLockSurface,   { "eglLockSurfaceKHR",   nullptr } },
            { (PRFuncPtr*) &mSymbols.fUnlockSurface, { "eglUnlockSurfaceKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &lockSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_lock_surface without exposing its functions!");

            MarkExtensionUnsupported(KHR_lock_surface);

            mSymbols.fLockSurface = nullptr;
            mSymbols.fUnlockSurface = nullptr;
        }
    }

    if (IsExtensionSupported(ANGLE_surface_d3d_texture_2d_share_handle)) {
        GLLibraryLoader::SymLoadStruct d3dSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fQuerySurfacePointerANGLE, { "eglQuerySurfacePointerANGLE", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &d3dSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports ANGLE_surface_d3d_texture_2d_share_handle without exposing its functions!");

            MarkExtensionUnsupported(ANGLE_surface_d3d_texture_2d_share_handle);

            mSymbols.fQuerySurfacePointerANGLE = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_fence_sync)) {
        GLLibraryLoader::SymLoadStruct syncSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateSync,     { "eglCreateSyncKHR",     nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroySync,    { "eglDestroySyncKHR",    nullptr } },
            { (PRFuncPtr*) &mSymbols.fClientWaitSync, { "eglClientWaitSyncKHR", nullptr } },
            { (PRFuncPtr*) &mSymbols.fGetSyncAttrib,  { "eglGetSyncAttribKHR",  nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &syncSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_fence_sync without exposing its functions!");

            MarkExtensionUnsupported(KHR_fence_sync);

            mSymbols.fCreateSync = nullptr;
            mSymbols.fDestroySync = nullptr;
            mSymbols.fClientWaitSync = nullptr;
            mSymbols.fGetSyncAttrib = nullptr;
        }
    }

    if (IsExtensionSupported(KHR_image) || IsExtensionSupported(KHR_image_base)) {
        GLLibraryLoader::SymLoadStruct imageSymbols[] = {
            { (PRFuncPtr*) &mSymbols.fCreateImage,  { "eglCreateImageKHR",  nullptr } },
            { (PRFuncPtr*) &mSymbols.fDestroyImage, { "eglDestroyImageKHR", nullptr } },
            { nullptr, { nullptr } }
        };

        bool success = GLLibraryLoader::LoadSymbols(mEGLLibrary,
                                                    &imageSymbols[0],
                                                    lookupFunction);
        if (!success) {
            NS_ERROR("EGL supports KHR_image(_base) without exposing its functions!");

            MarkExtensionUnsupported(KHR_image);
            MarkExtensionUnsupported(KHR_image_base);
            MarkExtensionUnsupported(KHR_image_pixmap);

            mSymbols.fCreateImage = nullptr;
            mSymbols.fDestroyImage = nullptr;
        }
    } else {
        MarkExtensionUnsupported(KHR_image_pixmap);
    }

    mInitialized = true;
    reporter.SetSuccessful();
    return true;
}