summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorchase@chromium.org <chase@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-21 00:08:22 +0000
committerchase@chromium.org <chase@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-21 00:08:22 +0000
commit887ba3adc7b32b7df315ef292ae9395fd75653e5 (patch)
tree0ce5c9ad4fd8c3c633093a58bd7180b958e2dd47 /webkit
parent6659178d57e1ee7d67f035d5c82e907b2fbbb7a0 (diff)
downloadchromium_src-887ba3adc7b32b7df315ef292ae9395fd75653e5.zip
chromium_src-887ba3adc7b32b7df315ef292ae9395fd75653e5.tar.gz
chromium_src-887ba3adc7b32b7df315ef292ae9395fd75653e5.tar.bz2
Revert "Erase the old NPAPI Pepper (Pepper 1) test plugin."
Manually reverting r69762, which broke the tree. This replays r69765, except also adds npapi_pepper_test_plugin back. BUG=none TEST=none TBR=dmaclach@chromium.org Review URL: http://codereview.chromium.org/6078002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69770 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/DEPS4
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/Info.plist46
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/main.cc64
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc233
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h60
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/plugin.def6
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/plugin.rc29
-rw-r--r--webkit/tools/npapi_pepper_test_plugin/test_factory.cc23
-rw-r--r--webkit/tools/test_shell/test_shell.gypi70
9 files changed, 535 insertions, 0 deletions
diff --git a/webkit/tools/npapi_pepper_test_plugin/DEPS b/webkit/tools/npapi_pepper_test_plugin/DEPS
new file mode 100644
index 0000000..f31c40db
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/DEPS
@@ -0,0 +1,4 @@
+include_rules = [
+ "+gpu/pgl",
+ "+third_party/gles2_book",
+]
diff --git a/webkit/tools/npapi_pepper_test_plugin/Info.plist b/webkit/tools/npapi_pepper_test_plugin/Info.plist
new file mode 100644
index 0000000..3d06b29
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/Info.plist
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+ <key>CFBundleDevelopmentRegion</key>
+ <string>English</string>
+ <key>CFBundleExecutable</key>
+ <string>${EXECUTABLE_NAME}</string>
+ <key>CFBundleGetInfoString</key>
+ <string>Copyright 2010 Google, Inc.</string>
+ <key>CFBundleIdentifier</key>
+ <string>com.google.testpepperplugin</string>
+ <key>CFBundleInfoDictionaryVersion</key>
+ <string>6.0</string>
+ <key>CFBundleName</key>
+ <string>${PRODUCT_NAME}</string>
+ <key>CFBundlePackageType</key>
+ <string>BRPL</string>
+ <key>CFBundleShortVersionString</key>
+ <string>1.0</string>
+ <key>CFBundleSignature</key>
+ <string>????</string>
+ <key>CFBundleVersion</key>
+ <string>1.0</string>
+ <key>CFPlugInDynamicRegisterFunction</key>
+ <string></string>
+ <key>CFPlugInDynamicRegistration</key>
+ <string>NO</string>
+ <key>WebPluginDescription</key>
+ <string>Simple NPAPI Pepper plug-in that handles tests</string>
+ <key>WebPluginMIMETypes</key>
+ <dict>
+ <key>pepper-application/x-pepper-test</key>
+ <dict>
+ <key>WebPluginExtensions</key>
+ <array>
+ <string>testpepper</string>
+ </array>
+ <key>WebPluginTypeDescription</key>
+ <string>Test Pepper API</string>
+ </dict>
+ </dict>
+ <key>WebPluginName</key>
+ <string>NPAPI Pepper Test PlugIn</string>
+</dict>
+</plist>
diff --git a/webkit/tools/npapi_pepper_test_plugin/main.cc b/webkit/tools/npapi_pepper_test_plugin/main.cc
new file mode 100644
index 0000000..78faa99
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/main.cc
@@ -0,0 +1,64 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define EXPORT __attribute__((visibility ("default")))
+#else
+#define EXPORT
+#endif
+
+#include "webkit/glue/plugins/test/plugin_client.h"
+
+extern "C" {
+EXPORT NPError API_CALL NP_GetEntryPoints(NPPluginFuncs* nppFuncs) {
+ return NPAPIClient::PluginClient::GetEntryPoints(nppFuncs);
+}
+
+EXPORT NPError API_CALL NP_Shutdown() {
+ return NPAPIClient::PluginClient::Shutdown();
+}
+
+#if defined(OS_POSIX) && !defined(OS_MACOSX)
+EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnFuncs,
+ NPPluginFuncs* nppFuncs) {
+ NPError error = NPAPIClient::PluginClient::Initialize(npnFuncs);
+ if (error == NPERR_NO_ERROR) {
+ error = NP_GetEntryPoints(nppFuncs);
+ }
+ return error;
+}
+
+EXPORT NPError API_CALL NP_GetValue(NPP instance, NPPVariable variable,
+ void* value) {
+ NPError err = NPERR_NO_ERROR;
+
+ switch (variable) {
+ case NPPVpluginNameString:
+ *(static_cast<const char**>(value)) = "NPAPI Pepper Test Plugin";
+ break;
+ case NPPVpluginDescriptionString:
+ *(static_cast<const char**>(value)) = "NPAPI Pepper Test Plugin";
+ break;
+ case NPPVpluginNeedsXEmbed:
+ *(static_cast<NPBool*>(value)) = true;
+ break;
+ default:
+ err = NPERR_GENERIC_ERROR;
+ break;
+ }
+
+ return err;
+}
+
+EXPORT const char* API_CALL NP_GetMIMEDescription() {
+ return "pepper-application/x-pepper-test:pepper:NPAPI Pepper Test Plugin";
+}
+#else // OS_POSIX
+EXPORT NPError API_CALL NP_Initialize(NPNetscapeFuncs* npnFuncs) {
+ return NPAPIClient::PluginClient::Initialize(npnFuncs);
+}
+#endif // OS_POSIX
+
+} // extern "C"
+
diff --git a/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc
new file mode 100644
index 0000000..a440dc6
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.cc
@@ -0,0 +1,233 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h"
+
+namespace {
+const int32 kCommandBufferSize = 1024 * 1024;
+} // namespace
+
+namespace NPAPIClient {
+
+Pepper3DTest::Pepper3DTest(NPP id, NPNetscapeFuncs *host_functions)
+ : PluginTest(id, host_functions),
+ pepper_extensions_(NULL),
+ device_3d_(NULL),
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ context_3d_(NULL),
+#endif
+ pgl_context_(PGL_NO_CONTEXT) {
+#if !defined(ENABLE_NEW_NPDEVICE_API)
+ memset(&context_3d_, 0, sizeof(context_3d_));
+#endif
+
+ esInitContext(&es_context_);
+ memset(&es_data_, 0, sizeof(es_data_));
+ es_context_.userData = &es_data_;
+}
+
+Pepper3DTest::~Pepper3DTest() {
+}
+
+NPError Pepper3DTest::New(uint16 mode, int16 argc, const char* argn[],
+ const char* argv[], NPSavedData* saved) {
+ return PluginTest::New(mode, argc, argn, argv, saved);
+}
+
+NPError Pepper3DTest::Destroy() {
+ DestroyContext();
+ pglTerminate();
+ return NPERR_NO_ERROR;
+}
+
+NPError Pepper3DTest::SetWindow(NPWindow* window) {
+ // Create context if needed.
+ CreateContext();
+
+ es_context_.width = window->width;
+ es_context_.height = window->height;
+
+ return NPERR_NO_ERROR;
+}
+
+void Pepper3DTest::RepaintCallback(NPP npp, NPDeviceContext3D* /* context */) {
+ Pepper3DTest* plugin = static_cast<Pepper3DTest*>(npp->pdata);
+ plugin->Paint();
+}
+
+void Pepper3DTest::CreateContext() {
+ if (pgl_context_ != PGL_NO_CONTEXT)
+ return;
+
+ HostFunctions()->getvalue(id(), NPNVPepperExtensions, &pepper_extensions_);
+ if (pepper_extensions_ == NULL) {
+ SetError("Could not acquire pepper extensions");
+ SignalTestCompleted();
+ return;
+ }
+
+ device_3d_ = pepper_extensions_->acquireDevice(id(), NPPepper3DDevice);
+ if (device_3d_ == NULL) {
+ SetError("Could not acquire 3D device");
+ SignalTestCompleted();
+ return;
+ }
+
+ // Initialize a 3D context.
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ int32 attrib_list[] = {
+ NP3DAttrib_CommandBufferSize, kCommandBufferSize,
+ NPAttrib_End
+ };
+ if (device_3d_->createContext(id(), 0, attrib_list,
+ reinterpret_cast<NPDeviceContext**>(&context_3d_)) != NPERR_NO_ERROR) {
+ SetError("Could not initialize 3D context");
+ SignalTestCompleted();
+ return;
+ }
+
+ device_3d_->registerCallback(
+ id(),
+ context_3d_,
+ NP3DCallback_Repaint,
+ reinterpret_cast<NPDeviceGenericCallbackPtr>(RepaintCallback),
+ NULL);
+#else
+ NPDeviceContext3DConfig config;
+ config.commandBufferSize = kCommandBufferSize;
+ if (device_3d_->initializeContext(id(), &config, &context_3d_)
+ != NPERR_NO_ERROR) {
+ SetError("Could not initialize 3D context");
+ SignalTestCompleted();
+ return;
+ }
+ context_3d_.repaintCallback = RepaintCallback;
+#endif // ENABLE_NEW_NPDEVICE_API
+
+ // Initialize PGL and create a PGL context.
+ if (!pglInitialize()) {
+ SetError("Could not initialize PGL");
+ SignalTestCompleted();
+ return;
+ }
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ pgl_context_ = pglCreateContext(id(), device_3d_, context_3d_);
+#else
+ pgl_context_ = pglCreateContext(id(), device_3d_, &context_3d_);
+#endif
+ if (pgl_context_ == PGL_NO_CONTEXT) {
+ SetError("Could not initialize PGL context");
+ SignalTestCompleted();
+ return;
+ }
+
+ // Initialize OpenGL.
+ MakeContextCurrent();
+ InitGL();
+ pglMakeCurrent(PGL_NO_CONTEXT);
+}
+
+void Pepper3DTest::DestroyContext() {
+ if (pgl_context_ == PGL_NO_CONTEXT)
+ return;
+
+ MakeContextCurrent();
+ ReleaseGL();
+ if (!pglDestroyContext(pgl_context_)) {
+ SetError("Could not destroy PGL context");
+ }
+ pgl_context_ = PGL_NO_CONTEXT;
+
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ if (device_3d_->destroyContext(id(), context_3d_) != NPERR_NO_ERROR) {
+ SetError("Could not destroy 3D context");
+ }
+#else
+ if (device_3d_->destroyContext(id(), &context_3d_) != NPERR_NO_ERROR) {
+ SetError("Could not destroy 3D context");
+ }
+#endif
+}
+
+void Pepper3DTest::MakeContextCurrent() {
+ DCHECK(pgl_context_ != PGL_NO_CONTEXT);
+
+ if (!pglMakeCurrent(pgl_context_)) {
+ SetError("Could not make PGL context current");
+ }
+}
+
+void Pepper3DTest::Paint() {
+ MakeContextCurrent();
+ DrawGL();
+ TestGL();
+ SwapBuffers();
+ pglMakeCurrent(PGL_NO_CONTEXT);
+
+ // Painting once is enough to check correctness.
+ SignalTestCompleted();
+}
+
+void Pepper3DTest::SwapBuffers() {
+ if (!pglSwapBuffers()) {
+ SetError("Could not swap buffers");
+ }
+}
+
+void Pepper3DTest::InitGL() {
+ if (!stInit(&es_context_)) {
+ SetError("Could not initialize OpenGL resources");
+ }
+}
+
+void Pepper3DTest::ReleaseGL() {
+ stShutDown(&es_context_);
+}
+
+void Pepper3DTest::DrawGL() {
+ stDraw(&es_context_);
+}
+
+void Pepper3DTest::TestGL() {
+ // NW quadrant is red.
+ GLint x = es_context_.width / 4;
+ GLint y = (3 * es_context_.height) / 4;
+ GLubyte red_color[3] = {255, 0, 0};
+ TestPixel(x, y, red_color);
+
+ // NE quadrant is green.
+ x = (3 * es_context_.width) / 4;
+ y = (3 * es_context_.height) / 4;
+ GLubyte green_color[3] = {0, 255, 0};
+ TestPixel(x, y, green_color);
+
+ // SW quadrant is blue.
+ x = es_context_.width / 4;
+ y = es_context_.height / 4;
+ GLubyte blue_color[3] = {0, 0, 255};
+ TestPixel(x, y, blue_color);
+
+ // SE quadrant is yellow.
+ x = (3 * es_context_.width) / 4;
+ y = es_context_.height / 4;
+ GLubyte yellow_color[3] = {255, 255, 0};
+ TestPixel(x, y, yellow_color);
+
+ // Mid-point is black.
+ x = es_context_.width / 2;
+ y = es_context_.height / 2;
+ GLubyte black_color[3] = {0, 0, 0};
+ TestPixel(x, y, black_color);
+}
+
+void Pepper3DTest::TestPixel(int x, int y, const GLubyte expected_color[3]) {
+ GLubyte pixel_color[4];
+ glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel_color);
+
+ ExpectIntegerEqual(pixel_color[0], expected_color[0]);
+ ExpectIntegerEqual(pixel_color[1], expected_color[1]);
+ ExpectIntegerEqual(pixel_color[2], expected_color[2]);
+}
+
+} // namespace NPAPIClient
diff --git a/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h
new file mode 100644
index 0000000..7b3e2db
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h
@@ -0,0 +1,60 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_TOOLS_NPAPI_PEPPER_TEST_PLUGIN_PEPPER_3D_TEST_H
+#define WEBKIT_TOOLS_NPAPI_PEPPER_TEST_PLUGIN_PEPPER_3D_TEST_H
+
+#include "gpu/pgl/pgl.h"
+#include "third_party/gles2_book/Chapter_11/Stencil_Test/Stencil_Test.h"
+#include "webkit/glue/plugins/test/plugin_test.h"
+
+namespace NPAPIClient {
+
+// This class contains a list of windowed plugin tests. Please add additional
+// tests to this class.
+class Pepper3DTest : public PluginTest {
+ public:
+ Pepper3DTest(NPP id, NPNetscapeFuncs *host_functions);
+ ~Pepper3DTest();
+
+ // Pepper tests run in windowless plugin mode.
+ virtual bool IsWindowless() const { return true; }
+
+ // NPAPI functions.
+ virtual NPError New(uint16 mode, int16 argc, const char* argn[],
+ const char* argv[], NPSavedData* saved);
+ virtual NPError Destroy();
+ virtual NPError SetWindow(NPWindow* window);
+
+ private:
+ static void RepaintCallback(NPP, NPDeviceContext3D*);
+
+ void CreateContext();
+ void DestroyContext();
+ void MakeContextCurrent();
+ void Paint();
+ void SwapBuffers();
+
+ void InitGL();
+ void ReleaseGL();
+ void DrawGL();
+ void TestGL();
+ void TestPixel(int x, int y, const GLubyte expected_color[3]);
+
+ NPExtensions* pepper_extensions_;
+ NPDevice* device_3d_;
+#if defined(ENABLE_NEW_NPDEVICE_API)
+ NPDeviceContext3D* context_3d_;
+#else
+ NPDeviceContext3D context_3d_;
+#endif
+ PGLContext pgl_context_;
+
+ ESContext es_context_;
+ STUserData es_data_;
+};
+
+} // namespace NPAPIClient
+
+#endif // WEBKIT_TOOLS_NPAPI_PEPPER_TEST_PLUGIN_PEPPER_3D_TEST_H
diff --git a/webkit/tools/npapi_pepper_test_plugin/plugin.def b/webkit/tools/npapi_pepper_test_plugin/plugin.def
new file mode 100644
index 0000000..2f62dfd
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/plugin.def
@@ -0,0 +1,6 @@
+LIBRARY npapi_pepper_test_plugin
+
+EXPORTS
+ NP_GetEntryPoints @1
+ NP_Initialize @2
+ NP_Shutdown @3
diff --git a/webkit/tools/npapi_pepper_test_plugin/plugin.rc b/webkit/tools/npapi_pepper_test_plugin/plugin.rc
new file mode 100644
index 0000000..6ee5243
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/plugin.rc
@@ -0,0 +1,29 @@
+1 VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x17L
+ FILEFLAGS 0x0L
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Google"
+ VALUE "FileDescription", "NPAPI Pepper Test Plugin"
+ VALUE "FileVersion", "1, 0, 0, 1"
+ VALUE "InternalName", "npapi_pepper_test_plugin"
+ VALUE "LegalCopyright", "Copyright (C) 2010"
+ VALUE "OriginalFilename", "npapi_pepper_test_plugin.dll"
+ VALUE "ProductName", "NPAPI Pepper Test Plugin"
+ VALUE "ProductVersion", "1, 0, 0, 1"
+ VALUE "MIMEType", "pepper-application/x-pepper-test"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
diff --git a/webkit/tools/npapi_pepper_test_plugin/test_factory.cc b/webkit/tools/npapi_pepper_test_plugin/test_factory.cc
new file mode 100644
index 0000000..95055f3
--- /dev/null
+++ b/webkit/tools/npapi_pepper_test_plugin/test_factory.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/glue/plugins/test/plugin_test_factory.h"
+
+#include "webkit/tools/npapi_pepper_test_plugin/pepper_3d_test.h"
+
+namespace NPAPIClient {
+
+PluginTest* CreatePluginTest(const std::string& test_name,
+ NPP instance,
+ NPNetscapeFuncs* host_functions) {
+ PluginTest* new_test = NULL;
+
+ if (test_name == "pepper_3d") {
+ new_test = new Pepper3DTest(instance, host_functions);
+ }
+
+ return new_test;
+}
+
+} // namespace NPAPIClient
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index 2a82ec3..9ebd278 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -654,6 +654,76 @@
}],
],
},
+ {
+ 'target_name': 'npapi_pepper_test_plugin',
+ 'type': 'loadable_module',
+ 'mac_bundle': 1,
+ 'msvs_guid': '821F3B89-6AE1-4254-99CB-93C04D0A79BE',
+ 'dependencies': [
+ '<(DEPTH)/gpu/gpu.gyp:pgl',
+ '<(DEPTH)/third_party/gles2_book/gles2_book.gyp:stencil_test',
+ 'npapi_test_common',
+ ],
+ 'sources': [
+ '../npapi_pepper_test_plugin/main.cc',
+ '../npapi_pepper_test_plugin/pepper_3d_test.cc',
+ '../npapi_pepper_test_plugin/pepper_3d_test.h',
+ '../npapi_pepper_test_plugin/plugin.def',
+ '../npapi_pepper_test_plugin/plugin.rc',
+ '../npapi_pepper_test_plugin/test_factory.cc',
+ ],
+ 'include_dirs': [
+ '../../..',
+ ],
+ 'conditions': [
+ ['OS!="win"', {
+ # windows-specific resources
+ 'sources!': [
+ '../npapi_pepper_test_plugin/plugin.def',
+ '../npapi_pepper_test_plugin/plugin.rc',
+ ],
+ }],
+ ['OS=="mac"', {
+ 'product_extension': 'plugin',
+ }],
+ ],
+ 'xcode_settings': {
+ 'INFOPLIST_FILE': '<(DEPTH)/webkit/tools/npapi_pepper_test_plugin/Info.plist',
+ },
+ },
+ {
+ 'target_name': 'copy_npapi_pepper_test_plugin',
+ 'type': 'none',
+ 'dependencies': [
+ 'npapi_pepper_test_plugin',
+ ],
+ 'conditions': [
+ ['OS=="win"', {
+ 'copies': [
+ {
+ 'destination': '<(PRODUCT_DIR)/plugins',
+ 'files': ['<(PRODUCT_DIR)/npapi_pepper_test_plugin.dll'],
+ },
+ ],
+ }],
+ ['OS=="mac"', {
+ 'copies': [
+ {
+ 'destination': '<(PRODUCT_DIR)/plugins/',
+ 'files': ['<(PRODUCT_DIR)/npapi_pepper_test_plugin.plugin/'],
+ },
+ ]
+ }],
+ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {
+ 'copies': [
+ {
+ 'destination': '<(PRODUCT_DIR)/plugins',
+ 'files': ['<(PRODUCT_DIR)/libnpapi_pepper_test_plugin.so'],
+ },
+ ],
+ }],
+ ],
+ },
],
}],
['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', {