diff options
author | binji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-09 18:36:32 +0000 |
---|---|---|
committer | binji@chromium.org <binji@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-09 18:36:32 +0000 |
commit | dbbf58beeaf1d170b61fa301e4ccd373f94e26e6 (patch) | |
tree | 3a629a72eb519f4c3705983d61be8a82aa91fd24 /native_client_sdk | |
parent | 1bc82369b4a3af57929d89ea520ef8720a1e0c38 (diff) | |
download | chromium_src-dbbf58beeaf1d170b61fa301e4ccd373f94e26e6.zip chromium_src-dbbf58beeaf1d170b61fa301e4ccd373f94e26e6.tar.gz chromium_src-dbbf58beeaf1d170b61fa301e4ccd373f94e26e6.tar.bz2 |
[NaCl SDK] Make the SDK examples buildable as a packaged app.
BUG=169313
Review URL: https://codereview.chromium.org/13488007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@193157 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'native_client_sdk')
65 files changed, 680 insertions, 454 deletions
diff --git a/native_client_sdk/src/build_tools/build_app.py b/native_client_sdk/src/build_tools/build_app.py new file mode 100755 index 0000000..d90fdff --- /dev/null +++ b/native_client_sdk/src/build_tools/build_app.py @@ -0,0 +1,147 @@ +#!/usr/bin/env python +# Copyright (c) 2013 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. + +import optparse +import os +import re +import sys + +if sys.version_info < (2, 6, 0): + sys.stderr.write("python 2.6 or later is required run this script\n") + sys.exit(1) + +import buildbot_common +import build_sdk +import build_utils +import easy_template +import generate_make + +sys.path.append(os.path.join(build_sdk.SDK_SRC_DIR, 'tools')) +import getos +import oshelpers + +# HACK: A few examples don't work properly as a packaged app right now. +EXAMPLE_LIST = [ +# 'debugging', + 'dlopen', + 'file_histogram', + 'file_io', + 'gamepad', + 'geturl', + 'hello_nacl_io', + 'hello_world_stdio', + 'hello_world', + 'hello_world_gles', +# 'hello_world_instance3d', + 'hello_world_interactive', + 'input_events', + 'load_progress', +# 'mouselock', + 'pi_generator', + 'sine_synth', + 'websocket', +] + + +def GenerateMake(outdir, toolchains): + args = ['--dstroot=%s' % outdir, '--master', '--config=Release', + '--first-valid-toolchain'] + for toolchain in toolchains: + args.append('--' + toolchain) + + for example in EXAMPLE_LIST: + dsc = os.path.join(build_sdk.SDK_EXAMPLE_DIR, example, 'example.dsc') + args.append(dsc) + + print "Generating Makefiles: %s" % str(args) + if generate_make.main(args): + buildbot_common.ErrorExit('Failed to build examples.') + + +def RemoveBuildCruft(outdir): + for root, _, files in os.walk(outdir): + for f in files: + path = os.path.join(root, f) + ext = os.path.splitext(path)[1] + if ext in ('.d', '.o'): + buildbot_common.RemoveFile(path) + elif f == 'dir.stamp': + buildbot_common.RemoveFile(path) + + +def StripNexes(outdir, platform, pepperdir): + for root, _, files in os.walk(outdir): + for f in files: + path = os.path.join(root, f) + m = re.search(r'lib(32|64).*\.so', path) + arch = None + if m: + # System .so file. Must be x86, because ARM doesn't support glibc yet. + arch = 'x86_' + m.group(1) + else: + basename, ext = os.path.splitext(f) + if ext in ('.nexe', '.so'): + # We can get the arch from the filename... + valid_arches = ('x86_64', 'x86_32', 'arm') + for a in valid_arches: + if basename.endswith(a): + arch = a + break + if not arch: + continue + + strip = GetStrip(pepperdir, platform, arch, 'newlib') + buildbot_common.Run([strip, path]) + + +def GetStrip(pepperdir, platform, arch, toolchain): + base_arch = {'x86_32': 'x86', 'x86_64': 'x86', 'arm': 'arm'}[arch] + bin_dir = os.path.join(pepperdir, 'toolchain', + '%s_%s_%s' % (platform, base_arch, toolchain), 'bin') + strip_prefix = {'x86_32': 'i686', 'x86_64': 'x86_64', 'arm': 'arm'}[arch] + strip_name = '%s-nacl-strip' % strip_prefix + return os.path.join(bin_dir, strip_name) + + +def main(args): + parser = optparse.OptionParser() + _, args = parser.parse_args(args[1:]) + + toolchains = ['newlib', 'glibc'] + + pepper_ver = str(int(build_utils.ChromeMajorVersion())) + pepperdir = os.path.join(build_sdk.OUT_DIR, 'pepper_' + pepper_ver) + app_dir = os.path.join(build_sdk.OUT_DIR, 'naclsdk_app') + app_examples_dir = os.path.join(app_dir, 'examples') + sdk_resources_dir = os.path.join(build_sdk.SDK_EXAMPLE_DIR, 'resources') + platform = getos.GetPlatform() + + buildbot_common.RemoveDir(app_dir) + buildbot_common.MakeDir(app_dir) + GenerateMake(app_dir, toolchains) + + easy_template.RunTemplateFile( + os.path.join(sdk_resources_dir, 'manifest.json.template'), + os.path.join(app_examples_dir, 'manifest.json'), + {'version': build_utils.ChromeVersionNoTrunk()}) + buildbot_common.CopyFile(os.path.join(sdk_resources_dir, 'background.js'), + os.path.join(app_examples_dir, 'background.js')) + + os.environ['NACL_SDK_ROOT'] = pepperdir + build_sdk.BuildStepMakeAll(app_dir, platform, 'examples', 'Build Examples', + False, False, 'Release') + + RemoveBuildCruft(app_dir) + StripNexes(app_dir, platform, pepperdir) + + app_zip = os.path.join(app_dir, 'examples.zip') + os.chdir(app_examples_dir) + oshelpers.Zip([app_zip, '-r', '*']) + + return 0 + + +if __name__ == '__main__': + sys.exit(main(sys.argv)) diff --git a/native_client_sdk/src/build_tools/build_utils.py b/native_client_sdk/src/build_tools/build_utils.py index 83df030..ffe8cf0 100644 --- a/native_client_sdk/src/build_tools/build_utils.py +++ b/native_client_sdk/src/build_tools/build_utils.py @@ -31,8 +31,18 @@ def ChromeVersion(): if info.url.startswith('/trunk/'): return 'trunk.%s' % info.revision else: - exec(open(VERSION_PATH).read()) - return '%s.%s.%s.%s' % (MAJOR, MINOR, BUILD, PATCH) + return ChromeVersionNoTrunk() + + +def ChromeVersionNoTrunk(): + '''Extract the chrome version from src/chrome/VERSION. + Ignore whether this is a trunk build. + + Returns: + Chrome version string. + ''' + exec(open(VERSION_PATH).read()) + return '%s.%s.%s.%s' % (MAJOR, MINOR, BUILD, PATCH) def ChromeMajorVersion(): diff --git a/native_client_sdk/src/build_tools/generate_index.py b/native_client_sdk/src/build_tools/generate_index.py index 5bfe23a..f5d9273 100644 --- a/native_client_sdk/src/build_tools/generate_index.py +++ b/native_client_sdk/src/build_tools/generate_index.py @@ -2,109 +2,22 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. -HTML_TOP = ''' -<!-- - Copyright (c) 2012 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. ---> - -<!DOCTYPE html> -<html> -<head> -<style type="text/css"> -dt { - font-weight: bold; -} -dd { - margin-bottom: 12pt; - width: 800px; -} -</style> -<link href="http://code.google.com/css/codesite.css" rel="stylesheet" - type="text/css" /> -<title>Native Client Examples</title> -</head> -<body> -<h1>Native Client Examples</h1> -<dd><p>This page lists all of the examples available in the most recent Native - Client SDK bundle. Each example is designed to teach a few specific Native - Client programming concepts. You will need to setup the build environment - including a path to 'make' which can be found in the 'tools' directory for - Windows, and the variable NACL_SDK_ROOT which points to one of the pepper - bundles found under the SDK install location. Calling make from the examples - directory will build all the projects, while calling make from an individual - example directory will build only that example. -</p></dd> -''' - -HTML_END = ''' -</body> -</html> -''' - -SECTIONS = { - 'API': """ -<h3>Common APIs</h3> -<dd><p>The following set of examples illustrate various Pepper APIs including -audio, 2D, 3D, file I/O, input and urls.</p></dd> - """, - 'Concepts': """ -<h3>Common Concepts</h3> -<dd><p>The following set of examples illustrate various common concepts such as -showing load progress, using Shared Objects (dynamic libraries), -mulithreading...</p></dd> -""", - 'Tools': """ -<h3>Using the Tools</h3> -<dd><p>The following "hello_world" examples, show the basic outline of a -several types of Native Client applications. The simplest, "Hello World Stdio" -uses several provided libraries to simplify startup and provides a -simplified make showing a single build configuration. The other examples in -this SDK however, are designed to build and run with multiple toolsets, build -configurations, etc... -making the build much more complex. In all cases we are using <a -href="http://www.gnu.org/software/make/manual/make.html">GNU Make</a>. -See the link for further information. -</p></dd> -""", -} +import collections +import easy_template class LandingPage(object): def __init__(self): self.section_list = ['Tools', 'API', 'Concepts'] - self.section_map = {} - for section in self.section_list: - self.section_map[section] = [] + self.section_map = collections.defaultdict(list) - def _ExampleDescription(self, index_path, title, details, focus): - return ''' - <dt><a href="%s/index.html">%s</a></dt> - <dd>%s - <p>Teaching focus: %s</p> - </dd> -''' % (index_path, title, details, focus) - - def _GenerateSection(self, section): - out = SECTIONS[section] - for desc in self.section_map[section]: - index_path = desc['NAME'] - title = desc['TITLE'] - details = desc['DESC'] - focus = desc['FOCUS'] - out += self._ExampleDescription(index_path, title, details, focus) - return out - - def GeneratePage(self): - out = HTML_TOP - for section in self.section_list: - out += self._GenerateSection(section) - out += HTML_END - return out + def GeneratePage(self, template_path): + with open(template_path) as src: + template = src.read() + template_dict = { 'section_map': self.section_map } + return easy_template.RunTemplateString(template, template_dict) def AddDesc(self, desc): group = desc['GROUP'] assert group in self.section_list self.section_map[group].append(desc) - diff --git a/native_client_sdk/src/build_tools/generate_make.py b/native_client_sdk/src/build_tools/generate_make.py index d04d07e..b7eab1b 100755 --- a/native_client_sdk/src/build_tools/generate_make.py +++ b/native_client_sdk/src/build_tools/generate_make.py @@ -87,11 +87,14 @@ def GetProjectObjects(source_dict): return object_list -def GetPlatforms(plat_list, plat_filter): +def GetPlatforms(plat_list, plat_filter, first_toolchain): platforms = [] for plat in plat_list: if plat in plat_filter: platforms.append(plat) + + if first_toolchain: + return [platforms[0]] return platforms @@ -103,7 +106,11 @@ DSC_FORMAT = { 'PREREQ' : (list, '', False), 'TARGETS' : (list, { 'NAME': (str, '', True), - 'TYPE': (str, ['main', 'lib', 'so'], True), + # main = nexe target + # lib = library target + # so = shared object target, automatically added to NMF + # so-standalone = shared object target, not put into NMF + 'TYPE': (str, ['main', 'lib', 'so', 'so-standalone'], True), 'SOURCES': (list, '', True), 'CCFLAGS': (list, '', False), 'CXXFLAGS': (list, '', False), @@ -124,8 +131,6 @@ DSC_FORMAT = { 'NAME': (str, '', False), 'DATA': (list, '', False), 'TITLE': (str, '', False), - 'DESC': (str, '', False), - 'FOCUS': (str, '', False), 'GROUP': (str, '', False), 'EXPERIMENTAL': (bool, [True, False], False) } @@ -253,17 +258,16 @@ def IsNexe(desc): return False -def ProcessHTML(srcroot, dstroot, desc, toolchains): +def ProcessHTML(srcroot, dstroot, desc, toolchains, configs, first_toolchain): name = desc['NAME'] outdir = os.path.join(dstroot, desc['DEST'], name) srcfile = os.path.join(srcroot, 'index.html') dstfile = os.path.join(outdir, 'index.html') - tools = GetPlatforms(toolchains, desc['TOOLS']) + tools = GetPlatforms(toolchains, desc['TOOLS'], first_toolchain) if use_gyp and getos.GetPlatform() != 'win': - configs = ['debug', 'release'] - else: - configs = ['Debug', 'Release'] + # Make the config names lowercase when using gyp... + configs = [c.lower() for c in configs] if use_gyp: path = "build/{tc}-{config}" @@ -323,7 +327,7 @@ def FindAndCopyFiles(src_files, root, search_dirs, dst_dir): buildbot_common.CopyFile(src_file, dst_file) -def ProcessProject(srcroot, dstroot, desc, toolchains): +def ProcessProject(srcroot, dstroot, desc, toolchains, first_toolchain): name = desc['NAME'] out_dir = os.path.join(dstroot, desc['DEST'], name) buildbot_common.MakeDir(out_dir) @@ -366,25 +370,14 @@ def ProcessProject(srcroot, dstroot, desc, toolchains): else: template = os.path.join(SCRIPT_DIR, 'library.mk') - tools = {} - tool_list = [] - for tool in desc['TOOLS']: - if ':' in tool: - tool, arch = tool.split(':') - else: - arch = None - # Ignore tools that are not enabled in this SDK build - if tool not in toolchains: - continue - tools.setdefault(tool, []) - if tool not in tool_list: - tool_list.append(tool) - if arch: - tools[tool].append(arch) - + # Ensure the order of |tools| is the same as toolchains; that way if + # first_toolchain is set, it will choose based on the order of |toolchains|. + tools = [tool for tool in toolchains if tool in desc['TOOLS']] + if first_toolchain: + tools = [tools[0]] template_dict = { 'pre': desc.get('PRE', ''), - 'tools': tool_list, + 'tools': tools, 'targets': desc['TARGETS'], } RunTemplateFile(template, make_path, template_dict) @@ -421,8 +414,13 @@ def main(argv): action='store_true') parser.add_option('--host', help='Create host examples.', action='store_true') + parser.add_option('--config', help='Add configuration (debug/release).', + action='append') parser.add_option('--experimental', help='Create experimental examples.', action='store_true') + parser.add_option('--first-valid-toolchain', + help='Only build one toolchain, the first one that is valid.', + action='store_true') parser.add_option('-v', '--verbose', help='Verbose output', action='store_true') @@ -448,9 +446,19 @@ def main(argv): if not toolchains: toolchains = ['newlib', 'glibc', 'pnacl'] + valid_configs = ['Debug', 'Release'] + if options.config: + configs = [] + for config in options.config: + if config in valid_configs: + configs.append(config) + else: + ErrorExit('Invalid config: %s' % config) + else: + configs = valid_configs + master_projects = {} - landing_page = LandingPage() for i, filename in enumerate(args): if i: # Print two newlines between each dsc file we process @@ -465,26 +473,39 @@ def main(argv): continue srcroot = os.path.dirname(os.path.abspath(filename)) - if not ProcessProject(srcroot, options.dstroot, desc, toolchains): + if not ProcessProject(srcroot, options.dstroot, desc, toolchains, + options.first_valid_toolchain): ErrorExit('\n*** Failed to process project: %s ***' % filename) # if this is an example update it's html file. if ShouldProcessHTML(desc): - ProcessHTML(srcroot, options.dstroot, desc, toolchains) - - # if this is an example, update landing page html file. - if desc['DEST'] == 'examples': - Trace('Adding desc: %s' % filename) - landing_page.AddDesc(desc) + ProcessHTML(srcroot, options.dstroot, desc, toolchains, configs, + options.first_valid_toolchain) # Create a list of projects for each DEST. This will be used to generate a # master makefile. master_projects.setdefault(desc['DEST'], []).append(desc) - # Generate the landing page text file. - index_html = os.path.join(options.dstroot, 'examples', 'index.html') - with open(index_html, 'w') as fh: - fh.write(landing_page.GeneratePage()) + + if master_projects.get('examples'): + landing_page = LandingPage() + for desc in master_projects.get('examples'): + landing_page.AddDesc(desc) + + # Generate the landing page text file. + index_html = os.path.join(options.dstroot, 'examples', 'index.html') + example_resources_dir = os.path.join(SDK_EXAMPLE_DIR, 'resources') + index_template = os.path.join(example_resources_dir, 'index.html.template') + with open(index_html, 'w') as fh: + fh.write(landing_page.GeneratePage(index_template)) + + # Copy additional files needed for the landing page. + extra_files = ['index.css', 'index.js', 'button_close.png', + 'button_close_hover.png'] + for filename in extra_files: + src_file = os.path.join(example_resources_dir, filename) + dst_file = os.path.join(options.dstroot, 'examples', filename) + buildbot_common.CopyFile(src_file, dst_file) if options.master: if use_gyp: diff --git a/native_client_sdk/src/build_tools/template.mk b/native_client_sdk/src/build_tools/template.mk index 3f413cd..ca5f2d4 100644 --- a/native_client_sdk/src/build_tools/template.mk +++ b/native_client_sdk/src/build_tools/template.mk @@ -91,6 +91,8 @@ $(foreach src,$({{name}}_SOURCES),$(eval $(call COMPILE_RULE,$(src),{{flags}}))) [[ name = target['NAME'] ]] [[ if target['TYPE'] == 'so':]] $(eval $(call SO_RULE,{{name}},$({{name}}_SOURCES))) +[[ elif target['TYPE'] == 'so-standalone':]] +$(eval $(call SO_RULE,{{name}},$({{name}}_SOURCES),,,1)) [[ else:]] $(eval $(call LINK_RULE,{{name}},$({{name}}_SOURCES),$(LIBS),$(DEPS))) [[]] diff --git a/native_client_sdk/src/examples/common.js b/native_client_sdk/src/examples/common.js index bd0a6b2..319c1f2 100644 --- a/native_client_sdk/src/examples/common.js +++ b/native_client_sdk/src/examples/common.js @@ -126,16 +126,25 @@ var common = (function () { return s.lastIndexOf(prefix, 0) === 0; } + /** Maximum length of logMessageArray. */ + var kMaxLogMessageLength = 20; + + /** An array of messages to display in the element with id "log". */ + var logMessageArray = []; + /** - * Add a message to an element with id "log", separated by a <br> element. + * Add a message to an element with id "log". * * This function is used by the default "log:" message handler. * * @param {string} message The message to log. */ function logMessage(message) { - var logEl = document.getElementById('log'); - logEl.innerHTML += message + '<br>'; + logMessageArray.push(message); + if (logMessageArray.length > kMaxLogMessageLength) + logMessageArray.shift(); + + document.getElementById('log').textContent = logMessageArray.join(''); console.log(message) } @@ -236,6 +245,7 @@ var common = (function () { domContentLoaded: domContentLoaded, createNaClModule: createNaClModule, hideModule: hideModule, + logMessage: logMessage, updateStatus: updateStatus }; diff --git a/native_client_sdk/src/examples/debugging/example.dsc b/native_client_sdk/src/examples/debugging/example.dsc index cb6abdd..376b6e0 100644 --- a/native_client_sdk/src/examples/debugging/example.dsc +++ b/native_client_sdk/src/examples/debugging/example.dsc @@ -37,10 +37,6 @@ CHROME_ENV+=NACL_UNTRUSTED_EXCEPTION_HANDLING=1 'DEST': 'examples', 'NAME': 'debugging', 'TITLE': 'Debugging', - 'DESC': """ -Debugging example shows how to use developer only features to enable -catching an exception, and then using that to create a stacktrace.""", - 'FOCUS': 'Debugging, Stacktraces.', 'GROUP': 'Concepts' } diff --git a/native_client_sdk/src/examples/dlopen/dlopen.cc b/native_client_sdk/src/examples/dlopen/dlopen.cc index b823e23..0a4e68b 100644 --- a/native_client_sdk/src/examples/dlopen/dlopen.cc +++ b/native_client_sdk/src/examples/dlopen/dlopen.cc @@ -30,6 +30,16 @@ #include "nacl_io/nacl_io.h" #include "reverse.h" +#if defined(NACL_SDK_DEBUG) +#define CONFIG_NAME "Debug" +#else +#define CONFIG_NAME "Release" +#endif + +#define XSTRINGIFY(x) STRINGIFY(x) +#define STRINGIFY(x) #x +#define NACL_ARCH_STRING XSTRINGIFY(NACL_ARCH) + class DlopenInstance : public pp::Instance { public: @@ -57,7 +67,7 @@ class DlopenInstance : public pp::Instance { // server. mount("", "/http", "httpfs", 0, ""); - logmsg("Spawning thread to cache .so files..."); + logmsg("Spawning thread to cache .so files...\n"); if (pthread_create(&tid_, NULL, LoadLibrariesOnWorker, this)) { logmsg("ERROR; pthread_create() failed.\n"); return false; @@ -69,9 +79,11 @@ class DlopenInstance : public pp::Instance { // the shared object. In addition, note that this function does NOT call // dlclose, which would close the shared object and unload it from memory. void LoadLibrary() { + const char reverse_so_path[] = + "/http/glibc/" CONFIG_NAME "/libreverse_" NACL_ARCH_STRING ".so"; const int32_t IMMEDIATELY = 0; eightball_so_ = dlopen("libeightball.so", RTLD_LAZY); - reverse_so_ = dlopen("/http/glibc/Debug/libreverse_x86_64.so", RTLD_LAZY); + reverse_so_ = dlopen(reverse_so_path, RTLD_LAZY); pp::CompletionCallback cc(LoadDoneCB, this); pp::Module::Get()->core()->CallOnMainThread(IMMEDIATELY, cc , 0); } @@ -91,9 +103,9 @@ class DlopenInstance : public pp::Instance { return; } - logmsg("Loaded libeightball.so"); + logmsg("Loaded libeightball.so\n"); } else { - logmsg("libeightball.so did not load"); + logmsg("libeightball.so did not load\n"); } @@ -107,34 +119,34 @@ class DlopenInstance : public pp::Instance { logmsg(message.c_str()); return; } - logmsg("Loaded libreverse.so"); + logmsg("Loaded libreverse.so\n"); } else { - logmsg("libreverse.so did not load"); + logmsg("libreverse.so did not load\n"); } } // Called by the browser to handle the postMessage() call in Javascript. virtual void HandleMessage(const pp::Var& var_message) { if (!var_message.is_string()) { - logmsg("Message is not a string."); + logmsg("Message is not a string.\n"); return; } std::string message = var_message.AsString(); if (message == "eightball") { if (NULL == eightball_){ - logmsg("Eightball library not loaded"); + logmsg("Eightball library not loaded\n"); return; } std::string ballmessage = "The Magic 8-Ball says: "; ballmessage += eightball_(); - ballmessage += "!"; + ballmessage += "!\n"; logmsg(ballmessage.c_str()); } else if (message.find("reverse:") == 0) { if (NULL == reverse_) { - logmsg("Reverse library not loaded"); + logmsg("Reverse library not loaded\n"); return; } @@ -143,7 +155,7 @@ class DlopenInstance : public pp::Instance { std::string message = "Your string reversed: \""; message += result; - message += "\""; + message += "\"\n"; free(result); diff --git a/native_client_sdk/src/examples/dlopen/example.dsc b/native_client_sdk/src/examples/dlopen/example.dsc index 4983a57..a68c0ff 100644 --- a/native_client_sdk/src/examples/dlopen/example.dsc +++ b/native_client_sdk/src/examples/dlopen/example.dsc @@ -16,7 +16,9 @@ }, { 'NAME' : 'libreverse', - 'TYPE' : 'so', + # This .so file is manually loaded by dlopen; we don't want to include it + # in the .nmf, or it will be automatically loaded on startup. + 'TYPE' : 'so-standalone', 'SOURCES' : ['reverse.cc', 'reverse.h'], 'CXXFLAGS': ['-fPIC'], 'LIBS' : ['ppapi_cpp', 'ppapi', 'pthread'] @@ -28,13 +30,6 @@ 'DEST': 'examples', 'NAME': 'dlopen', 'TITLE': 'Dynamic Library Open', - 'DESC': """ -The dlopen example demonstrates how build dynamic libraries and then -open and use them at runtime. When the page loads, type in a question and -hit enter or click the ASK! button. The question and answer will be -displayed in the page under the text entry box. Shared libraries are only -available with the GLIBC toolchain.""", - 'FOCUS': 'Using shared objects.', 'GROUP': 'Concepts' } diff --git a/native_client_sdk/src/examples/dlopen/example.js b/native_client_sdk/src/examples/dlopen/example.js index bb658cd..5e1b1e3 100644 --- a/native_client_sdk/src/examples/dlopen/example.js +++ b/native_client_sdk/src/examples/dlopen/example.js @@ -19,7 +19,7 @@ function askBall(event) { var questionEl = document.getElementById('question'); var query = questionEl.value; questionEl.value = ''; - document.getElementById('log').innerHTML += 'You asked:' + query + '<br>'; + common.logMessage('You asked: ' + query + '\n'); common.naclModule.postMessage('eightball'); event.preventDefault(); } @@ -28,7 +28,6 @@ function reverseString(event) { var questionEl = document.getElementById('question'); var query = questionEl.value; questionEl.value = ''; - - document.getElementById('log').innerHTML += 'Reversing:' + query + '<br>'; + common.logMessage('Reversing: ' + query + '\n'); common.naclModule.postMessage('reverse:' + query); } diff --git a/native_client_sdk/src/examples/dlopen/index.html b/native_client_sdk/src/examples/dlopen/index.html index 4ad4f54..0e535b4 100644 --- a/native_client_sdk/src/examples/dlopen/index.html +++ b/native_client_sdk/src/examples/dlopen/index.html @@ -15,8 +15,13 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <div>Magic eightball: type a question below, press the button, and get a - response.</div> + <p>The dlopen example demonstrates how build dynamic libraries and then + open and use them at runtime. When the page loads, type in a question and + hit enter or click the ASK! button. The question and answer will be + displayed in the page under the text entry box. Shared libraries are only + available with the GLIBC toolchain.</p> + <p>Magic eightball: type a question below, press the button, and get a + response.</p> <form> <input type="text" id="question" value=""> <input type="submit" value="ASK!"> @@ -26,6 +31,6 @@ found in the LICENSE file. <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> - <div id="log"></div> + <pre id="log" style="font-weight: bold"></pre> </body> </html> diff --git a/native_client_sdk/src/examples/file_histogram/example.dsc b/native_client_sdk/src/examples/file_histogram/example.dsc index da805c7..af8dbac 100644 --- a/native_client_sdk/src/examples/file_histogram/example.dsc +++ b/native_client_sdk/src/examples/file_histogram/example.dsc @@ -14,12 +14,6 @@ 'DEST': 'examples', 'NAME': 'file_histogram', 'TITLE': 'File Histogram.', - 'DESC': """ -The File Histogram example demonstrates prompting the user for a file, -passing the file contents to NativeClient as a VarArrayBuffer, then drawing a -histogram representing the contents of the file to a 2D square. -""", - 'FOCUS': 'VarArrayBuffer, 2D, File input.', 'GROUP': 'API' } diff --git a/native_client_sdk/src/examples/file_histogram/index.html b/native_client_sdk/src/examples/file_histogram/index.html index 74fb107..53858d9 100644 --- a/native_client_sdk/src/examples/file_histogram/index.html +++ b/native_client_sdk/src/examples/file_histogram/index.html @@ -15,6 +15,10 @@ <body data-width="256" data-height="256" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> + <p>The File Histogram example demonstrates prompting the user for a file, + passing the file contents to NativeClient as a VarArrayBuffer, then + drawing a histogram representing the contents of the file to a 2D + square.</p> <input type="file" id="fileInput" multiple> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> diff --git a/native_client_sdk/src/examples/file_io/example.dsc b/native_client_sdk/src/examples/file_io/example.dsc index b9bf3e6..2a1d207 100644 --- a/native_client_sdk/src/examples/file_io/example.dsc +++ b/native_client_sdk/src/examples/file_io/example.dsc @@ -14,10 +14,6 @@ 'DEST': 'examples', 'NAME': 'file_io', 'TITLE': 'File I/O', - 'DESC': """ -The File IO example demonstrates saving, loading, and deleting files -from the persistent file store.""", - 'FOCUS': 'File input and output.', 'GROUP': 'API' } diff --git a/native_client_sdk/src/examples/file_io/index.html b/native_client_sdk/src/examples/file_io/index.html index 64767b2..7625bd6 100644 --- a/native_client_sdk/src/examples/file_io/index.html +++ b/native_client_sdk/src/examples/file_io/index.html @@ -15,6 +15,8 @@ <body data-width="200" data-height="200" data-custom-load="true" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> + <p>The File IO example demonstrates saving, loading, and deleting files + from the persistent file store.</p> <textarea id="fileEditor" cols="40" @@ -22,7 +24,7 @@ wrap="hard" placeholder="Enter some text to save in a file..."></textarea> <br>File Name - <input type="text" id="fileName" action=""> + <input type="text" id="fileName" action="" value="/filename.txt"> <button id="saveButton" action="">Save</button> <button id="loadButton" action="">Load</button> <button id="deleteButton" action="">Delete</button> diff --git a/native_client_sdk/src/examples/fullscreen_tumbler/index.html b/native_client_sdk/src/examples/fullscreen_tumbler/index.html index 315743e..bf902f2 100644 --- a/native_client_sdk/src/examples/fullscreen_tumbler/index.html +++ b/native_client_sdk/src/examples/fullscreen_tumbler/index.html @@ -20,11 +20,6 @@ found in the LICENSE file. <body data-width="480" data-height="480" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <p> - The Native Client module executed in this page draws a 3D cube - and allows you to rotate it using a virtual trackball method. To toggle - the view to/from fullscreen, press the Enter key. - </p> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> diff --git a/native_client_sdk/src/examples/gamepad/example.dsc b/native_client_sdk/src/examples/gamepad/example.dsc index 2d6102e..8a494b5 100644 --- a/native_client_sdk/src/examples/gamepad/example.dsc +++ b/native_client_sdk/src/examples/gamepad/example.dsc @@ -11,11 +11,6 @@ 'DEST': 'examples', 'NAME': 'gamepad', 'TITLE': 'Gamepad Example.', - 'DESC': """ -Attached gamepad values should appear, left to right, once they've been -interacted with. Buttons, esp triggers are analog. -""", - 'FOCUS': 'Gamepad interface.', 'GROUP': 'API' } diff --git a/native_client_sdk/src/examples/gamepad/index.html b/native_client_sdk/src/examples/gamepad/index.html index 108319b..8b580db 100644 --- a/native_client_sdk/src/examples/gamepad/index.html +++ b/native_client_sdk/src/examples/gamepad/index.html @@ -14,10 +14,10 @@ found in the LICENSE file. <body data-width="800" data-height="200" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <!-- The NaCl plugin will be embedded inside the element with id "listener". - See common.js.--> <p> Attached gamepad values should appear, left to right, once they've been interacted with. Buttons, esp triggers are analog. </p> + <!-- The NaCl plugin will be embedded inside the element with id "listener". + See common.js.--> <div id="listener"></div> </body> </html> diff --git a/native_client_sdk/src/examples/geturl/example.dsc b/native_client_sdk/src/examples/geturl/example.dsc index eff4fc3..4f5b1c8 100644 --- a/native_client_sdk/src/examples/geturl/example.dsc +++ b/native_client_sdk/src/examples/geturl/example.dsc @@ -15,12 +15,6 @@ 'DEST': 'examples', 'NAME': 'geturl', 'TITLE': 'Get URL', - 'DESC': """ -The Get URL example demonstrates fetching an URL and then displaying -its contents. Clicking the GetURL button will cause a geturl_success.html -file to get loaded asynchronously, then displayed in a text box when the -load completes.""", - 'FOCUS': 'URL loading.', 'GROUP': 'API' } diff --git a/native_client_sdk/src/examples/geturl/index.html b/native_client_sdk/src/examples/geturl/index.html index ceb42ad..cdaa241 100644 --- a/native_client_sdk/src/examples/geturl/index.html +++ b/native_client_sdk/src/examples/geturl/index.html @@ -15,6 +15,10 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> + <p>The Get URL example demonstrates fetching an URL and then displaying its + contents. Clicking the GetURL button will cause a geturl_success.html + file to get loaded asynchronously, then displayed in a text box when the + load completes.</p> <table border=5 cellpadding=5% summary="A title and a result log"> <tr> <td valign=top><pre id='generalOutput' class='notrun'></pre></td> diff --git a/native_client_sdk/src/examples/hello_nacl_io/example.dsc b/native_client_sdk/src/examples/hello_nacl_io/example.dsc index 8f6f759..8a4bc0b 100644 --- a/native_client_sdk/src/examples/hello_nacl_io/example.dsc +++ b/native_client_sdk/src/examples/hello_nacl_io/example.dsc @@ -21,11 +21,5 @@ 'DEST': 'examples', 'NAME': 'hello_nacl_io', 'TITLE': 'Hello, Nacl IO!', - 'DESC': """ -The NaCl IO example demonstrates mapping standard FILE such as fopen, -fread, fwrite into mounts by linking in the nacl_io library. This allows -developers to wrap Pepper API such as the File IO API or URL Loader into -standard blocking calls.""", - 'FOCUS': 'Using NaCl IO.', 'GROUP': 'Concepts' } diff --git a/native_client_sdk/src/examples/hello_nacl_io/example.js b/native_client_sdk/src/examples/hello_nacl_io/example.js index c355b4d..e764c21 100644 --- a/native_client_sdk/src/examples/hello_nacl_io/example.js +++ b/native_client_sdk/src/examples/hello_nacl_io/example.js @@ -78,7 +78,7 @@ function fopen_result(filename, filehandle) { filehandle_map[filehandle] = filename; addFilenameToSelectElements(filehandle, filename) - logMessage('File ' + filename + ' opened successfully.'); + common.logMessage('File ' + filename + ' opened successfully.\n'); } function fclose(e) { @@ -89,7 +89,7 @@ function fclose(e) { function fclose_result(filehandle) { var filename = filehandle_map[filehandle]; removeFilenameFromSelectElements(filehandle, filename); - logMessage('File ' + filename + ' closed successfully.'); + common.logMessage('File ' + filename + ' closed successfully.\n'); } function fread(e) { @@ -100,7 +100,7 @@ function fread(e) { function fread_result(filehandle, data) { var filename = filehandle_map[filehandle]; - logMessage('Read "' + data + '" from file ' + filename + '.'); + common.logMessage('Read "' + data + '" from file ' + filename + '.\n'); } function fwrite(e) { @@ -111,7 +111,8 @@ function fwrite(e) { function fwrite_result(filehandle, bytes_written) { var filename = filehandle_map[filehandle]; - logMessage('Wrote ' + bytes_written + ' bytes to file ' + filename + '.'); + common.logMessage('Wrote ' + bytes_written + ' bytes to file ' + filename + + '.\n'); } function fseek(e) { @@ -123,7 +124,8 @@ function fseek(e) { function fseek_result(filehandle, filepos) { var filename = filehandle_map[filehandle]; - logMessage('Seeked to location ' + filepos + ' in file ' + filename + '.'); + common.logMessage('Seeked to location ' + filepos + ' in file ' + filename + + '.\n'); } /** @@ -138,19 +140,6 @@ function startsWith(s, prefix) { return s.lastIndexOf(prefix, 0) === 0; } -function logMessage(msg) { - var logEl = document.getElementById('log'); - - // Perform some basic escaping. - msg = msg.replace(/&/g, '&') - .replace(/</g, '<') - .replace(/>/g, '>') - .replace(/"/g, '"') - .replace(/'/g, '''); - - logEl.innerHTML += msg + '<br>'; -} - function makeCall(func) { var message = func; for (var i = 1; i < arguments.length; ++i) { @@ -164,7 +153,7 @@ function makeCall(func) { function handleMessage(message_event) { var msg = message_event.data; if (startsWith(msg, 'Error:')) { - logMessage(msg); + common.logMessage(msg + '\n'); } else { // Result from a function call. var params = msg.split('\1'); @@ -173,7 +162,7 @@ function handleMessage(message_event) { var result_func = window[func_result_name]; if (!result_func) { - logMessage('Error: Bad message received from NaCl module.'); + common.logMessage('Error: Bad message received from NaCl module.\n'); return; } diff --git a/native_client_sdk/src/examples/hello_nacl_io/index.html b/native_client_sdk/src/examples/hello_nacl_io/index.html index 8695747..baed38d 100644 --- a/native_client_sdk/src/examples/hello_nacl_io/index.html +++ b/native_client_sdk/src/examples/hello_nacl_io/index.html @@ -97,9 +97,9 @@ found in the LICENSE file. <button id="fseekExecute">fseek</button> </span> </div> + <pre id="log" style="font-weight: bold"></pre> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> - <div id="log"></div> </body> </html> diff --git a/native_client_sdk/src/examples/hello_world/example.dsc b/native_client_sdk/src/examples/hello_world/example.dsc index d7453d8..850bf66 100644 --- a/native_client_sdk/src/examples/hello_world/example.dsc +++ b/native_client_sdk/src/examples/hello_world/example.dsc @@ -14,12 +14,5 @@ 'DEST': 'examples', 'NAME': 'hello_world', 'TITLE': 'Hello World.', - 'DESC': """ -The Hello World In C example demonstrates the basic structure of all -Native Client applications. This example loads a Native Client module. The -page tracks the status of the module as it load. On a successful load, the -module will post a message containing the string "Hello World" back to -JavaScript which will display it as an alert.""", - 'FOCUS': 'Basic HTML, JavaScript, and module architecture.', 'GROUP': 'Tools' } diff --git a/native_client_sdk/src/examples/hello_world/example.js b/native_client_sdk/src/examples/hello_world/example.js index 13a9997..7f26921 100644 --- a/native_client_sdk/src/examples/hello_world/example.js +++ b/native_client_sdk/src/examples/hello_world/example.js @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var kMaxArraySize = 20; -var messageArray = new Array(); - // Once we load, hide the plugin function moduleDidLoad() { common.hideModule(); @@ -12,13 +9,5 @@ function moduleDidLoad() { // Called by the common.js module. function handleMessage(message) { - // Show last |kMaxArraySize| events in html. - messageArray.push(message.data); - if (messageArray.length > kMaxArraySize) { - messageArray.shift(); - } - var newData = messageArray.join('<BR>'); - document.getElementById('outputString').innerHTML = newData; - // Print event to console. - console.log(message.data); + common.logMessage(message.data); } diff --git a/native_client_sdk/src/examples/hello_world/index.html b/native_client_sdk/src/examples/hello_world/index.html index a91a547e..4ed2986 100644 --- a/native_client_sdk/src/examples/hello_world/index.html +++ b/native_client_sdk/src/examples/hello_world/index.html @@ -15,22 +15,15 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <p>This example demonstrates a complete NaCl PPAPI application. In -source file hello_world.c contains the three required PPAPI functions - PPP_InitializeModule, PPP_GetInterface, PPP_ShutdownModule which initialize -the application, provide a string name to callback interface mapping, and -cleanup on shutdown respectively.</p> - <p>The example will query for the Console, PostMessage and Var interfaces to -send a message to JavaScript which will be added to the output box. In -addition, it will send another message to the JavaScript Console to simulate -logging for development.</p> - + <p>The Hello World In C example demonstrates the basic structure of all + Native Client applications. This example loads a Native Client module. The + page tracks the status of the module as it load. On a successful load, the + module will post a message containing the string "Hello World" back to + JavaScript which will display it as an alert.</p> + <h2>Output:</h2> + <pre id="log" style="font-weight: bold"></pre> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> - <h1>OUTPUT</h1> - <pre> - <p><b id='outputString'></b></p> - </pre> </body> </html> diff --git a/native_client_sdk/src/examples/hello_world_gles/example.dsc b/native_client_sdk/src/examples/hello_world_gles/example.dsc index 5178253..eda6f3d 100644 --- a/native_client_sdk/src/examples/hello_world_gles/example.dsc +++ b/native_client_sdk/src/examples/hello_world_gles/example.dsc @@ -20,11 +20,6 @@ 'DEST': 'examples', 'NAME': 'hello_world_gles', 'TITLE': 'Hello World GLES 2.0', - 'DESC': """ -The Hello World GLES 2.0 example demonstrates how to create a 3D cube -that rotates. This is a simpler example than the tumbler example, and -written in C. It loads the assets using URLLoader.""", - 'FOCUS': '3D graphics, URL Loader.', 'GROUP': 'API' } diff --git a/native_client_sdk/src/examples/hello_world_gles/index.html b/native_client_sdk/src/examples/hello_world_gles/index.html index b07ff78..665ce4e 100644 --- a/native_client_sdk/src/examples/hello_world_gles/index.html +++ b/native_client_sdk/src/examples/hello_world_gles/index.html @@ -14,6 +14,8 @@ found in the LICENSE file. <body data-width="640" data-height="480" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> + <p>The Hello World GLES 2.0 example demonstrates how to create a 3D cube + that rotates. It loads the assets using URLLoader.</p> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> diff --git a/native_client_sdk/src/examples/hello_world_instance3d/example.dsc b/native_client_sdk/src/examples/hello_world_instance3d/example.dsc index 2ba6eb1..4180cad 100644 --- a/native_client_sdk/src/examples/hello_world_instance3d/example.dsc +++ b/native_client_sdk/src/examples/hello_world_instance3d/example.dsc @@ -21,11 +21,6 @@ 'DEST': 'examples', 'NAME': 'hello_world_instance3d', 'TITLE': 'Hello World GLES 2.0 using ppapi_instance3d', - 'DESC': """ -The Hello World GLES 2.0 example demonstrates how to create a 3D cube -that rotates. This is a simpler example than the tumbler example, and -written in C. It loads the assets using URLLoader.""", - 'FOCUS': '3D graphics, URL Loader.', 'GROUP': 'API' } diff --git a/native_client_sdk/src/examples/hello_world_instance3d/index.html b/native_client_sdk/src/examples/hello_world_instance3d/index.html index b07ff78..fa132dc 100644 --- a/native_client_sdk/src/examples/hello_world_instance3d/index.html +++ b/native_client_sdk/src/examples/hello_world_instance3d/index.html @@ -14,6 +14,15 @@ found in the LICENSE file. <body data-width="640" data-height="480" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> + <p> + The Hello World instance3d example is similar to the Hello World GLES 2.0 + example, but uses the ppapi_main and nacl_io libraries to simplify the code: + <ul> + <li>URL loading is handled by a synchronous read from an HTTP mount.</li> + <li>Instance creation is hidden; instead the functions ppapi_main and + PPAPIRender are used.</li> + </ul> + </p> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> diff --git a/native_client_sdk/src/examples/hello_world_interactive/example.dsc b/native_client_sdk/src/examples/hello_world_interactive/example.dsc index 6f0d65c..c113eab 100644 --- a/native_client_sdk/src/examples/hello_world_interactive/example.dsc +++ b/native_client_sdk/src/examples/hello_world_interactive/example.dsc @@ -18,13 +18,6 @@ 'DEST': 'examples', 'NAME': 'hello_world_interactive', 'TITLE': 'Interactive Hello World in C++', - 'DESC': """ -The Interactive Hello World C++ example demonstrates the basic structure -of all Native Client applications. This example loads a Native Client module -which uses two way interaction with JavaScript whenever a button is clicked. -The NaCl module will respond with the number 42 or the reversed version of the -string in the text box when the appropriate button is clicked.""", - 'FOCUS': 'Basic HTML, JavaScript, C++ PPAPI, and Messaging API.', 'GROUP': 'Tools' } diff --git a/native_client_sdk/src/examples/hello_world_interactive/example.js b/native_client_sdk/src/examples/hello_world_interactive/example.js index 9e2a88f..7058f73 100644 --- a/native_client_sdk/src/examples/hello_world_interactive/example.js +++ b/native_client_sdk/src/examples/hello_world_interactive/example.js @@ -25,7 +25,12 @@ function reverseText() { common.naclModule.postMessage('reverseText:' + inputBox.value); } -// Called by the common.js module. -function handleMessage(message_event) { - alert(message_event.data); +function handleMessage(e) { + if (typeof e.data === 'string') { + // Received a reversed message. + common.logMessage('Received "' + e.data + '"\n'); + } else if (typeof e.data === 'number') { + // Recived 42. + common.logMessage('Received "' + e.data + '"\n'); + } } diff --git a/native_client_sdk/src/examples/hello_world_interactive/index.html b/native_client_sdk/src/examples/hello_world_interactive/index.html index 44e0b30..bba2379 100644 --- a/native_client_sdk/src/examples/hello_world_interactive/index.html +++ b/native_client_sdk/src/examples/hello_world_interactive/index.html @@ -15,13 +15,22 @@ <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <!-- The NaCl plugin will be embedded inside the element with id "listener". - See common.js.--> - <div id="listener"></div> + <p>The Interactive Hello World C++ example demonstrates the basic structure + of all Native Client applications. This example loads a Native Client + module which uses two way interaction with JavaScript whenever a button + is clicked. The NaCl module will respond with the number 42 or the + reversed version of the string in the text box when the appropriate + button is clicked.</p> <textarea id="inputBox" rows="4" cols="50">Hello World</textarea> <div> <button id="fortyTwo">Call fortyTwo()</button> <button id="reverseText">Call reverseText()</button> <div/> + <h2>Output:</h2> + <pre id="log" style="font-weight:bold"></pre> + + <!-- The NaCl plugin will be embedded inside the element with id "listener". + See common.js.--> + <div id="listener"></div> </body> </html> diff --git a/native_client_sdk/src/examples/hello_world_stdio/example.dsc b/native_client_sdk/src/examples/hello_world_stdio/example.dsc index bc88727..d0737bd 100644 --- a/native_client_sdk/src/examples/hello_world_stdio/example.dsc +++ b/native_client_sdk/src/examples/hello_world_stdio/example.dsc @@ -14,15 +14,6 @@ 'DEST': 'examples', 'NAME': 'hello_world_stdio', 'TITLE': 'Hello World STDIO.', - 'DESC': """ - - The Hello World Stdio example is the simplest one in the SDK. It uses the -ppapi_main library which creates an Module and Instance, using default values -to simplify setup and communication with the PPAPI system. In addition, it -uses the nacl_io library to remap IO to the Pepper API. This -simplifies IO by providing a standard blocking API and allowing STDERR to go to -the JavaScript console by default.""", - 'FOCUS': 'Basic HTML, JavaScript, Minimal App.', 'GROUP': 'Tools' } diff --git a/native_client_sdk/src/examples/hello_world_stdio/example.js b/native_client_sdk/src/examples/hello_world_stdio/example.js index 13a9997..7f26921 100644 --- a/native_client_sdk/src/examples/hello_world_stdio/example.js +++ b/native_client_sdk/src/examples/hello_world_stdio/example.js @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var kMaxArraySize = 20; -var messageArray = new Array(); - // Once we load, hide the plugin function moduleDidLoad() { common.hideModule(); @@ -12,13 +9,5 @@ function moduleDidLoad() { // Called by the common.js module. function handleMessage(message) { - // Show last |kMaxArraySize| events in html. - messageArray.push(message.data); - if (messageArray.length > kMaxArraySize) { - messageArray.shift(); - } - var newData = messageArray.join('<BR>'); - document.getElementById('outputString').innerHTML = newData; - // Print event to console. - console.log(message.data); + common.logMessage(message.data); } diff --git a/native_client_sdk/src/examples/hello_world_stdio/hello_world.c b/native_client_sdk/src/examples/hello_world_stdio/hello_world.c index be1c397..e553da5 100644 --- a/native_client_sdk/src/examples/hello_world_stdio/hello_world.c +++ b/native_client_sdk/src/examples/hello_world_stdio/hello_world.c @@ -13,12 +13,13 @@ #include "ppapi_main/ppapi_main.h" -// Have the Module object provided by ppapi_main create a basic -// PPAPI instance with default arguments which mounts the dev -// file system providing /dev/null, /dev/tty, and /devl/console3 -// for null STDIN, STDOUT directed to PostMessage and STDERR -// directed to the JavaScript Console with LogLevel 'ERROR' -PPAPI_MAIN_WITH_DEFAULT_ARGS +// The default arguments to PPAPI_MAIN maps: +// STDIN -> /dev/stdin +// STDOUT -> /dev/stdout +// STDERR -> /dev/console3 +// We use our own args here so that stdout sends messages to JavaScript via +// PostMessage (/dev/tty). +PPAPI_MAIN_WITH_ARGS("pm_stdout", "/dev/tty", NULL, NULL) // // The "main" entry point called by PPAPIInstance once initialization diff --git a/native_client_sdk/src/examples/hello_world_stdio/index.html b/native_client_sdk/src/examples/hello_world_stdio/index.html index f317883..c6a4aa1 100644 --- a/native_client_sdk/src/examples/hello_world_stdio/index.html +++ b/native_client_sdk/src/examples/hello_world_stdio/index.html @@ -15,23 +15,19 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <!-- The NaCl plugin will be embedded inside the element with id "listener". - See common.js.--> - - <p>This example demonstrates using nacl_io ppapi_main to simplify the - creation of a PPAPI application. The ppapi_main library handles the creation - and initialization of a pp::Instance object. The nacl_io library - intercepts standard file IO, allowing the remapping of STDOUT, and - STDERR.</p> + <p>The Hello World Stdio example is the simplest one in the SDK. It uses the + ppapi_main library which creates an Module and Instance, using default + values to simplify setup and communication with the PPAPI system. In + addition, it uses the nacl_io library to remap IO to the Pepper API. This + simplifies IO by providing a standard blocking API and allowing STDERR to + go to the JavaScript console by default.</p> <p>In main, we write to both STDOUT and STDERR, printing a hello world - message.</p> + message.</p> <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> + <h2>Output:</h2> + <pre id="log" style="font-weight:bold"></pre> <div id="listener"></div> - <h1>OUTPUT</h1> - <pre> - <p><b id='outputString'></b></p> - </pre> </body> </html> diff --git a/native_client_sdk/src/examples/input_events/custom_events.cc b/native_client_sdk/src/examples/input_events/custom_events.cc index 9e22808..fe304c5 100644 --- a/native_client_sdk/src/examples/input_events/custom_events.cc +++ b/native_client_sdk/src/examples/input_events/custom_events.cc @@ -53,7 +53,7 @@ std::string ModifierToString(uint32_t modifier) { std::string KeyEvent::ToString() const { std::ostringstream stream; - stream << " Key event:" + stream << "Key event:" << " modifier:" << string_event_modifiers() << " key_code:" << key_code_ << " time:" << timestamp_ @@ -64,7 +64,7 @@ std::string KeyEvent::ToString() const { std::string MouseEvent::ToString() const { std::ostringstream stream; - stream << " Mouse event:" + stream << "Mouse event:" << " modifier:" << string_event_modifiers() << " button:" << MouseButtonToString(mouse_button_) << " x:" << x_position_ @@ -77,7 +77,7 @@ std::string MouseEvent::ToString() const { std::string WheelEvent::ToString() const { std::ostringstream stream; - stream << "Wheel event." + stream << "Wheel event:" << " modifier:" << string_event_modifiers() << " deltax:" << delta_x_ << " deltay:" << delta_y_ @@ -144,7 +144,7 @@ void TouchEvent::AddTouch(uint32_t id, float x, float y, float radii_x, std::string TouchEvent::ToString() const { std::ostringstream stream; - stream << " Touch event:" << KindToString(kind_) + stream << "Touch event:" << KindToString(kind_) << " modifier:" << string_event_modifiers(); for (size_t i = 0; i < touches.size(); ++i) { const Touch& touch = touches[i]; diff --git a/native_client_sdk/src/examples/input_events/example.dsc b/native_client_sdk/src/examples/input_events/example.dsc index cdcd287..014815c 100644 --- a/native_client_sdk/src/examples/input_events/example.dsc +++ b/native_client_sdk/src/examples/input_events/example.dsc @@ -19,13 +19,6 @@ 'DEST': 'examples', 'NAME': 'input_events', 'TITLE': 'Input Events', - 'DESC': """The Input Events example shows how to handle input events in a -multi-threaded application. The main thread converts input events to -non-pepper events and puts them on a queue. The worker thread pulls them off of -the queue, converts them to a string, and then uses CallOnMainThread so that -PostMessage can be send the result of the worker thread to the browser.""", - 'FOCUS': """Multi-threading, keyboard and mouse input, view change, and focus -events.""", 'GROUP': 'API', } diff --git a/native_client_sdk/src/examples/input_events/example.js b/native_client_sdk/src/examples/input_events/example.js index eb335f0..003e843 100644 --- a/native_client_sdk/src/examples/input_events/example.js +++ b/native_client_sdk/src/examples/input_events/example.js @@ -2,9 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -var kMaxArraySize = 20; -var messageArray = new Array(); - // Called by the common.js module. function moduleDidLoad() { common.naclModule.style.backgroundColor = 'gray'; @@ -17,15 +14,7 @@ function attachListeners() { // Called by the common.js module. function handleMessage(message) { - // Show last |kMaxArraySize| events in html. - messageArray.push(message.data); - if (messageArray.length > kMaxArraySize) { - messageArray.shift(); - } - var newData = messageArray.join('<BR>'); - document.getElementById('eventString').innerHTML = newData; - // Print event to console. - console.log(message.data); + common.logMessage(message.data); } function cancelQueue() { diff --git a/native_client_sdk/src/examples/input_events/index.html b/native_client_sdk/src/examples/input_events/index.html index a77af1f..2e97b98 100644 --- a/native_client_sdk/src/examples/input_events/index.html +++ b/native_client_sdk/src/examples/input_events/index.html @@ -15,28 +15,24 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <button id="killButton">Kill worker thread and queue</button> - - <p>This example demonstrates handling of input events in PPAPI.</p> - <p>Each time an input event happens in the context of the gray box, the main - thread in the embedded NaCl module converts it from a Pepper input event to a - non-Pepper event and puts this custom event onto a shared queue. A worker - thread in the embedded NaCl module reads events from the queue, and converts - each event to a string and then uses CallOnMainThread to post a message - describing the event back to JavaScript, which prints a message to the - JavaScript console in Chrome and to a string on the page.</p> + <p>The Input Events example shows how to handle input events in a + multi-threaded application. The main thread converts input events to + non-pepper events and puts them on a queue. The worker thread pulls them + off of the queue, converts them to a string, and then uses + CallOnMainThread so that PostMessage can be send the result of the worker + thread to the browser.</p> <p>If you press the 'Kill worker thread and queue' button, then the main thread (which puts events on the queue) will call CancelQueue, indicating that the main thread will no longer put events on the queue. When the worker sees that the shared queue has been cancelled, the worker thread will terminate.</p> + <button id="killButton">Kill worker thread and queue</button> + <!-- The NaCl plugin will be embedded inside the element with id "listener". See common.js.--> <div id="listener"></div> - <h2>Events</h2> - <pre> - <p><b id='eventString'>None</b></p> - </pre> + <h2>Events:</h2> + <pre id="log" style="font-weight: bold"></pre> </body> </html> diff --git a/native_client_sdk/src/examples/input_events/input_events.cc b/native_client_sdk/src/examples/input_events/input_events.cc index 1a0a9f8..a216f0a 100644 --- a/native_client_sdk/src/examples/input_events/input_events.cc +++ b/native_client_sdk/src/examples/input_events/input_events.cc @@ -27,11 +27,11 @@ #endif namespace event_queue { -const char* const kDidChangeView = "DidChangeView"; -const char* const kHandleInputEvent = "DidHandleInputEvent"; -const char* const kDidChangeFocus = "DidChangeFocus"; -const char* const kHaveFocus = "HaveFocus"; -const char* const kDontHaveFocus = "DontHaveFocus"; +const char* const kDidChangeView = "DidChangeView\n"; +const char* const kHandleInputEvent = "DidHandleInputEvent\n"; +const char* const kDidChangeFocus = "DidChangeFocus\n"; +const char* const kHaveFocus = "HaveFocus\n"; +const char* const kDontHaveFocus = "DontHaveFocus\n"; const char* const kCancelMessage = "CANCEL"; // Convert a pepper inputevent modifier value into a diff --git a/native_client_sdk/src/examples/load_progress/example.dsc b/native_client_sdk/src/examples/load_progress/example.dsc index 22372cc..8d5f68b 100644 --- a/native_client_sdk/src/examples/load_progress/example.dsc +++ b/native_client_sdk/src/examples/load_progress/example.dsc @@ -14,13 +14,6 @@ 'DEST': 'examples', 'NAME': 'load_progress', 'TITLE': 'Load Progress', - 'DESC': """ -The Load Progress example demonstrates how to listen for and handle -events that occur while a NaCl module loads. This example listens for -different load event types and dispatches different events to their -respective handler. This example also checks for valid browser version and -shows how to calculate and display loading progress.""", - 'FOCUS': 'Progress event handling.', 'GROUP': 'Concepts' } diff --git a/native_client_sdk/src/examples/load_progress/example.js b/native_client_sdk/src/examples/load_progress/example.js index 37c3079..8e7c00d 100644 --- a/native_client_sdk/src/examples/load_progress/example.js +++ b/native_client_sdk/src/examples/load_progress/example.js @@ -20,7 +20,7 @@ function domContentLoaded(name, tc, config, width, height) { // event is always triggered when an <EMBED> tag has a MIME type of // application/x-nacl. function moduleDidStartLoad() { - appendToEventLog('loadstart'); + common.logMessage('loadstart\n'); } // Progress event handler. |event| contains a couple of interesting @@ -44,8 +44,8 @@ function moduleLoadProgress(event) { loadPercent = -1.0; loadPercentString = 'Computing...'; } - appendToEventLog('progress: ' + loadPercentString + - ' (' + event.loaded + ' of ' + event.total + ' bytes)'); + common.logMessage('progress: ' + loadPercentString + + ' (' + event.loaded + ' of ' + event.total + ' bytes)\n'); } // Handler that gets called if an error occurred while loading the NaCl @@ -53,17 +53,17 @@ function moduleLoadProgress(event) { // the error, you have to check lastError on the <EMBED> element to find // out what happened. function moduleLoadError() { - appendToEventLog('error: ' + common.naclModule.lastError); + common.logMessage('error: ' + common.naclModule.lastError + '\n'); } // Handler that gets called if the NaCl module load is aborted. function moduleLoadAbort() { - appendToEventLog('abort'); + common.logMessage('abort\n'); } // When the NaCl module has loaded indicate success. function moduleDidLoad() { - appendToEventLog('load'); + common.logMessage('load\n'); common.updateStatus('SUCCESS'); } @@ -74,27 +74,15 @@ function moduleDidLoad() { // that if the NaCl module loads successfully, you will get both a 'load' // event and a 'loadend' event. function moduleDidEndLoad() { - appendToEventLog('loadend'); + common.logMessage('loadend\n'); var lastError = event.target.lastError; if (lastError == undefined || lastError.length == 0) { - lastError = '<none>'; + lastError = '<none>'; } - appendToEventLog('lastError: ' + lastError); + common.logMessage('lastError: ' + lastError + '\n'); } // Handle a message coming from the NaCl module. function handleMessage(message_event) { - alert(message_event.data); -} - -// Append an event name to the 'log' element. Event names -// are separated by a <br> tag so they get listed one per line. -// logMessage The message to append to the log. -function appendToEventLog(logMessage) { - var eventLogField = document.getElementById('log'); - if (eventLogField.innerHTML.length == 0) { - eventLogField.innerHTML = logMessage; - } else { - eventLogField.innerHTML = eventLogField.innerHTML + '<br>' + logMessage; - } + common.logMessage('Received PostMessage: ' + message_event.data + '\n'); } diff --git a/native_client_sdk/src/examples/load_progress/index.html b/native_client_sdk/src/examples/load_progress/index.html index 8b2c0b6..108fc05 100644 --- a/native_client_sdk/src/examples/load_progress/index.html +++ b/native_client_sdk/src/examples/load_progress/index.html @@ -15,8 +15,13 @@ found in the LICENSE file. <body data-width="256" data-height="256" data-custom-load="true" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <h2>Event Log</h2> + <p>The Load Progress example demonstrates how to listen for and handle events + that occur while a NaCl module loads. This example listens for different + load event types and dispatches different events to their respective + handler. This example also checks for valid browser version and shows + how to calculate and display loading progress.</p> + <h2>Events:</h2> + <pre id="log" style="font-weight: bold"></pre> <div id="listener"></div> - <div id="log"></div> </body> </html> diff --git a/native_client_sdk/src/examples/mouselock/example.dsc b/native_client_sdk/src/examples/mouselock/example.dsc index 03fb60a..478fe48 100644 --- a/native_client_sdk/src/examples/mouselock/example.dsc +++ b/native_client_sdk/src/examples/mouselock/example.dsc @@ -11,12 +11,6 @@ 'DEST': 'examples', 'NAME': 'mouselock', 'TITLE': 'Mouse Lock', - 'DESC': """ -The Mouselock example demonstrates how to use the MouseLock API to hide -the mouse cursor. Mouse lock is only available in full-screen mode. You can -lock and unlock the mouse while in full-screen mode by pressing the Enter key. -""", - 'FOCUS': 'Mouse lock, Full-screen.', 'GROUP': 'Concepts' } diff --git a/native_client_sdk/src/examples/mouselock/index.html b/native_client_sdk/src/examples/mouselock/index.html index 4ccf96b..c50377b 100644 --- a/native_client_sdk/src/examples/mouselock/index.html +++ b/native_client_sdk/src/examples/mouselock/index.html @@ -14,7 +14,6 @@ found in the LICENSE file. <body data-width="300" data-height="300" {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <h1>Full-screen and Mouse-lock Example</h1> <ul> <li>There are two different kinds of fullscreen mode: "tab fullscreen" and "browser fullscreen". diff --git a/native_client_sdk/src/examples/pi_generator/example.dsc b/native_client_sdk/src/examples/pi_generator/example.dsc index 3910abd..3bdba19 100644 --- a/native_client_sdk/src/examples/pi_generator/example.dsc +++ b/native_client_sdk/src/examples/pi_generator/example.dsc @@ -18,10 +18,5 @@ 'DEST': 'examples', 'NAME': 'pi_generator', 'TITLE': 'Monte Carlo Estimate for Pi', - 'DESC': """ -The Pi Generator example demonstrates creating a helper thread that -estimate pi using the Monte Carlo method while randomly putting 1,000,000,000 -points inside a 2D square that shares two sides with a quarter circle.""", - 'FOCUS': 'Thread creation, 2D graphics, view change events.', 'GROUP': 'Concepts' } diff --git a/native_client_sdk/src/examples/resources/background.js b/native_client_sdk/src/examples/resources/background.js new file mode 100644 index 0000000..1fc5a19b --- /dev/null +++ b/native_client_sdk/src/examples/resources/background.js @@ -0,0 +1,13 @@ +// Copyright (c) 2013 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. + +function onLaunched(launchData) { + chrome.app.window.create('index.html', { + width: 1024, + height: 800, + frame: 'none' + }); +} + +chrome.app.runtime.onLaunched.addListener(onLaunched); diff --git a/native_client_sdk/src/examples/resources/index.css b/native_client_sdk/src/examples/resources/index.css new file mode 100644 index 0000000..93f2663 --- /dev/null +++ b/native_client_sdk/src/examples/resources/index.css @@ -0,0 +1,88 @@ +/* Copyright (c) 2013 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. */ + +html { + color: #222; + font-family: Arial, san-serif; +} +body { + margin: 0; +} +.main-column { + background-color: #fff; + display: -webkit-flex; + height: 100%; + position: absolute; + -webkit-flex-direction: column; + width: 100%; +} +.header, .footer, .left-border, .right-border { + background-color: #444; + -webkit-flex: none; +} +.header { + color: #fff; + font-size: 150%; + font-weight: bold; + padding: 2px; + -webkit-app-region: drag; +} +.left-border, .right-border { + width: 2px; +} +.footer { + height: 2px; +} +.close-button { + background-image: url('button_close.png'); + float: right; + height: 17px; + margin: 8px 2px; + text-align: center; + -webkit-app-region: no-drag; + width: 17px; +} +.close-button:hover { + background-image: url('button_close_hover.png'); +} +.main { + display: -webkit-flex; + min-height: 0; + -webkit-flex: 1; + -webkit-flex-direction: row; +} +.nav-wrapper { + overflow-y: auto; +} +.nav { + padding: 8px; + -webkit-flex: initial; +} +.nav-group-header { + font-weight: bold; + padding: 4px 0; +} +.nav-item { + cursor: pointer; + font-size: 13px; + padding: 4px 0; +} +.nav-item:hover { + background-color: #eee; +} +.selected { + color: #dd4b39; +} +.nav-title { + padding-left: 8px; +} +.iframe-wrapper { + overflow-y: auto; + -webkit-flex: auto; +} +iframe { + border: none; + width: 100%; + height: auto; +} diff --git a/native_client_sdk/src/examples/resources/index.html.template b/native_client_sdk/src/examples/resources/index.html.template new file mode 100644 index 0000000..cc192e3 --- /dev/null +++ b/native_client_sdk/src/examples/resources/index.html.template @@ -0,0 +1,43 @@ +<!-- + Copyright (c) 2013 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. +--> +<!DOCTYPE html> +<html> +<head> + <title>Native Client SDK</title> + <link href="index.css" rel="stylesheet" type="text/css"> + <script src="index.js"></script> +</head> +<body> + <div class="main-column"> + <div class="header"> + Native Client SDK + <div class="close-button"></div> + </div> + <div class="main"> + <div class="left-border"></div> + <div class="nav-wrapper"> + <div class="nav"> +[[for section in 'Tools', 'API', 'Concepts':]] + <div class="nav-group-header">{{section}}</div> +[[ for desc in section_map[section]:]] + <div class="nav-item" data-href="{{desc['NAME']}}/index.html"> + <div class="nav-title"> + {{desc['TITLE']}} + </div> + </div> +[[]] + </div> + </div> + <div class="iframe-wrapper"> + <iframe scrolling="no"> + </iframe> + </div> + <div class="right-border"></div> + </div> + <div class="footer"></div> + </div> +</body> +</html> diff --git a/native_client_sdk/src/examples/resources/index.js b/native_client_sdk/src/examples/resources/index.js new file mode 100644 index 0000000..ab4b4ff --- /dev/null +++ b/native_client_sdk/src/examples/resources/index.js @@ -0,0 +1,72 @@ +// Copyright (c) 2013 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. + +var iframeUpdateIntervalID; + +function selectExample(el) { + setIframeSrc(el.dataset.href); + deselectAllNavItems(); + selectNavItem(el); +} + +function selectNavItem(el) { + el.classList.add('selected'); +} + +function deselectAllNavItems() { + var navItemEls = document.querySelectorAll('.nav-item'); + for (var i = 0; i < navItemEls.length; ++i) { + navItemEls[i].classList.remove('selected'); + } +} + +function setIframeSrc(src) { + var iframeEl = document.querySelector('iframe'); + + window.clearInterval(iframeUpdateIntervalID); + iframeEl.style.height = ''; + iframeEl.src = src; +} + +document.addEventListener('DOMContentLoaded', function () { + var iframeEl = document.querySelector('iframe'); + var iframeWrapperEl = document.querySelector('.iframe-wrapper'); + var navItemEls = document.querySelectorAll('.nav-item'); + + for (var i = 0; i < navItemEls.length; ++i) { + navItemEls[i].addEventListener('click', function (e) { + selectExample(this); + }); + } + + iframeEl.addEventListener('load', function () { + var iframeDocument = this.contentWindow.document; + var iframeBodyEl = iframeDocument.body; + iframeEl.style.height = iframeBodyEl.scrollHeight + 'px'; + + // HACK: polling the body height to update the iframe. There's got to be a + // better way to do this... + var prevBodyHeight; + var prevWrapperHeight; + iframeUpdateIntervalID = window.setInterval(function () { + var bodyHeight = iframeBodyEl.getBoundingClientRect().height; + var wrapperHeight = iframeWrapperEl.clientHeight; + if (bodyHeight != prevBodyHeight || wrapperHeight != prevWrapperHeight) { + // HACK: magic 4... without it, the scrollbar is always visible. :( + var newHeight = Math.max(wrapperHeight - 4, bodyHeight); + iframeEl.style.height = newHeight + 'px'; + prevBodyHeight = bodyHeight; + prevWrapperHeight = wrapperHeight; + } + }, 100); // .1s + }, false); + + var closeButtonEl = document.querySelector('.close-button'); + closeButtonEl.addEventListener('click', function () { + window.close(); + }); + + // select the first example. + selectExample(document.querySelector('.nav-item')); +}); diff --git a/native_client_sdk/src/examples/resources/manifest.json.template b/native_client_sdk/src/examples/resources/manifest.json.template new file mode 100644 index 0000000..e8a8faa --- /dev/null +++ b/native_client_sdk/src/examples/resources/manifest.json.template @@ -0,0 +1,17 @@ +{ + "name": "Native Client SDK", + "version": "{{version}}", + "manifest_version": 2, + "description": "Native Client SDK examples, showing API use and key concepts.", + "offline_enabled": true, + "app": { + "background": { + "scripts": ["background.js"] + } + }, + "permissions": [ + "fullscreen", + "pointerLock", + "unlimitedStorage" + ] +} diff --git a/native_client_sdk/src/examples/sine_synth/example.dsc b/native_client_sdk/src/examples/sine_synth/example.dsc index ceb5112..8e01041 100644 --- a/native_client_sdk/src/examples/sine_synth/example.dsc +++ b/native_client_sdk/src/examples/sine_synth/example.dsc @@ -14,11 +14,6 @@ 'DEST': 'examples', 'NAME': 'sine_synth', 'TITLE': 'Sine Wave Synthesizer', - 'DESC': """ -The Sine Wave Synthesizer example demonstrates playing sound (a sine -wave). Enter the desired frequency and hit play to start, stop to end. The -frequency box will display "Loading, please wait." while the module loads.""", - 'FOCUS': 'Audio.', 'GROUP': 'API', } diff --git a/native_client_sdk/src/examples/sine_synth/index.html b/native_client_sdk/src/examples/sine_synth/index.html index f2f66a3..70e8ed2 100644 --- a/native_client_sdk/src/examples/sine_synth/index.html +++ b/native_client_sdk/src/examples/sine_synth/index.html @@ -15,8 +15,10 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> + <p>The Sine Wave Synthesizer example demonstrates playing sound (a sine + wave). Enter the desired frequency and hit play to start, stop to end.</p> - <p>Click the button to start and stop the sine wave playing.</p> + <p>Click the buttons to start and stop the sine wave playing.</p> <button id="playButton">Play</button> <button id="stopButton">Stop</button> diff --git a/native_client_sdk/src/examples/websocket/example.dsc b/native_client_sdk/src/examples/websocket/example.dsc index bf98bfc..e5c7e21 100644 --- a/native_client_sdk/src/examples/websocket/example.dsc +++ b/native_client_sdk/src/examples/websocket/example.dsc @@ -14,12 +14,5 @@ 'DEST': 'examples', 'NAME': 'websocket', 'TITLE': 'Websocket', - 'DESC': """ -The Websocket example demonstrates how to use the Websocket API. The -user first connects to the test server: ws://html5rocks.websocket.org/echo by -clicking on the 'Connect'' button. Then hitting Send' will cause the app to -send the message to the server and retrieve the reply.""", - 'FOCUS': 'Websockets', 'GROUP': 'API' } - diff --git a/native_client_sdk/src/examples/websocket/example.js b/native_client_sdk/src/examples/websocket/example.js index cc99dd3..561d044 100644 --- a/native_client_sdk/src/examples/websocket/example.js +++ b/native_client_sdk/src/examples/websocket/example.js @@ -34,3 +34,7 @@ function doClose() { // Send a request message. See also websocket.cc for the request format. common.naclModule.postMessage('c;'); } + +function handleMessage(message) { + common.logMessage(message.data + '\n'); +} diff --git a/native_client_sdk/src/examples/websocket/index.html b/native_client_sdk/src/examples/websocket/index.html index 2bd2b18..f077fcd 100644 --- a/native_client_sdk/src/examples/websocket/index.html +++ b/native_client_sdk/src/examples/websocket/index.html @@ -15,10 +15,12 @@ found in the LICENSE file. <body {{attrs}}> <h1>{{title}}</h1> <h2>Status: <code id="statusField">NO-STATUS</code></h2> - <div>Set a server URL, then push "Connect" button to establish a connection. - <br>"Send" button sends text message on the left text area. - <br>"Close" button closes the connection. - <div> + <p>The Websocket example demonstrates how to use the Websocket API.<br> + First set a server URL (or use the default), then push "Connect" button to + establish a connection.<br> + "Send" button sends text message on the left text area.<br> + "Close" button closes the connection. + </p> <form id="connectForm"> <input type="text" id="url" style="width: 400px" value="ws://html5rocks.websocket.org/echo?encoding=text"> @@ -31,7 +33,7 @@ found in the LICENSE file. </form> <button id="closeButton">Close</button> + <pre id="log" style="font-weight: bold"></pre> <div id="listener"></div> - <div id="log"></div> </body> </html> diff --git a/native_client_sdk/src/examples/websocket/websocket.cc b/native_client_sdk/src/examples/websocket/websocket.cc index fc1f0ed..fd42934 100644 --- a/native_client_sdk/src/examples/websocket/websocket.cc +++ b/native_client_sdk/src/examples/websocket/websocket.cc @@ -77,7 +77,7 @@ void WebSocketInstance::Open(const std::string& url) { if (!websocket_) return; websocket_->Connect(pp::Var(url), NULL, 0, callback); - PostMessage(pp::Var("log:connecting...")); + PostMessage(pp::Var("connecting...")); } void WebSocketInstance::Close() { @@ -92,7 +92,7 @@ void WebSocketInstance::Send(const std::string& message) { if (!IsConnected()) return; websocket_->SendMessage(pp::Var(message)); - PostMessage(pp::Var(std::string("log:send: ") + message)); + PostMessage(pp::Var(std::string("send: ") + message)); } void WebSocketInstance::Receive() { @@ -104,25 +104,25 @@ void WebSocketInstance::Receive() { void WebSocketInstance::OnConnectCompletion(int32_t result) { if (result != PP_OK) { - PostMessage(pp::Var("alert:connection failed")); + PostMessage(pp::Var("connection failed")); return; } - PostMessage(pp::Var("log:connected")); + PostMessage(pp::Var("connected")); Receive(); } void WebSocketInstance::OnCloseCompletion(int32_t result) { PostMessage(pp::Var(PP_OK == result ? - "log:closed" : - "alert:abnormally closed")); + "closed" : + "abnormally closed")); } void WebSocketInstance::OnReceiveCompletion(int32_t result) { if (result == PP_OK) { if (receive_var_.is_array_buffer()) - PostMessage(pp::Var("log: receive: binary data")); + PostMessage(pp::Var("receive: binary data")); else - PostMessage(pp::Var(std::string("log:receive: ") + + PostMessage(pp::Var(std::string("receive: ") + receive_var_.AsString())); } Receive(); diff --git a/native_client_sdk/src/libraries/nacl_io/mount_http.cc b/native_client_sdk/src/libraries/nacl_io/mount_http.cc index ea3f93f..c50d9fe 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_http.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_http.cc @@ -233,11 +233,14 @@ int MountNodeHttp::GetStat(struct stat* stat) { size_t entity_length; - if (ParseContentLength(response_headers, &entity_length)) + if (ParseContentLength(response_headers, &entity_length)) { SetCachedSize(static_cast<off_t>(entity_length)); - else + } else if (cache_content_ && !has_cached_size_) { + DownloadToCache(); + } else { // Don't use SetCachedSize here -- it is actually unknown. stat_.st_size = 0; + } stat_.st_atime = 0; // TODO(binji): Use "Last-Modified". stat_.st_mtime = 0; diff --git a/native_client_sdk/src/libraries/nacl_io/mount_node.cc b/native_client_sdk/src/libraries/nacl_io/mount_node.cc index d31b99f..823a138 100644 --- a/native_client_sdk/src/libraries/nacl_io/mount_node.cc +++ b/native_client_sdk/src/libraries/nacl_io/mount_node.cc @@ -85,15 +85,15 @@ void* MountNode::MMap(void* addr, size_t length, int prot, int flags, void* new_addr = addr; int err = _real_mmap(&new_addr, length, prot | PROT_WRITE, flags | MAP_ANONYMOUS, -1, 0); - if (addr == MAP_FAILED) { - _real_munmap(addr, length); + if (new_addr == MAP_FAILED) { + _real_munmap(new_addr, length); errno = err; return MAP_FAILED; } - ssize_t cnt = Read(offset, addr, length); + ssize_t cnt = Read(offset, new_addr, length); if (cnt == -1) { - _real_munmap(addr, length); + _real_munmap(new_addr, length); errno = ENOSYS; return MAP_FAILED; } diff --git a/native_client_sdk/src/libraries/ppapi_main/ppapi_main.h b/native_client_sdk/src/libraries/ppapi_main/ppapi_main.h index af5217a..9bfe5b5 100644 --- a/native_client_sdk/src/libraries/ppapi_main/ppapi_main.h +++ b/native_client_sdk/src/libraries/ppapi_main/ppapi_main.h @@ -41,15 +41,11 @@ void PPAPIRender(uint32_t width, uint32_t height); EXTERN_C_END -#define PPAPI_MAIN_DEFAULT_ARGS \ - { \ - NULL, NULL \ - } +#define PPAPI_MAIN_DEFAULT_ARGS NULL, NULL - -#define PPAPI_MAIN_USE(factory, args) \ +#define PPAPI_MAIN_USE(factory, ...) \ void* UserCreateInstance(PP_Instance inst) { \ - static const char *params[] = args; \ + static const char *params[] = { __VA_ARGS__ }; \ return factory(inst, params); \ } @@ -59,8 +55,8 @@ void* UserCreateInstance(PP_Instance inst) { \ #define PPAPI_MAIN_3D_WITH_DEFAULT_ARGS \ PPAPI_MAIN_USE(PPAPI_CreateInstance3D, PPAPI_MAIN_DEFAULT_ARGS) -#define PPAPI_MAIN_WITH_ARGS(args) \ - PPAPI_MAIN_USE(PPAPI_CreateInstance, args) +#define PPAPI_MAIN_WITH_ARGS(...) \ + PPAPI_MAIN_USE(PPAPI_CreateInstance, __VA_ARGS__) #endif // PPAPI_MAIN_PPAPI_MAIN_H_ diff --git a/native_client_sdk/src/tools/common.mk b/native_client_sdk/src/tools/common.mk index 3e3388c..1082bd5 100644 --- a/native_client_sdk/src/tools/common.mk +++ b/native_client_sdk/src/tools/common.mk @@ -239,7 +239,7 @@ endif ifeq ($(CONFIG),Release) POSIX_FLAGS?=-g -O2 -pthread -MMD else -POSIX_FLAGS?=-g -O0 -pthread -MMD +POSIX_FLAGS?=-g -O0 -pthread -MMD -DNACL_SDK_DEBUG endif NACL_CFLAGS?=-Wno-long-long -Werror diff --git a/native_client_sdk/src/tools/host_vc.mk b/native_client_sdk/src/tools/host_vc.mk index fb62167..ac2fbd4f 100644 --- a/native_client_sdk/src/tools/host_vc.mk +++ b/native_client_sdk/src/tools/host_vc.mk @@ -28,7 +28,7 @@ endif ifeq ('Debug','$(CONFIG)') -WIN_OPT_FLAGS?=/Od /MTd /Z7 +WIN_OPT_FLAGS?=/Od /MTd /Z7 -D NACL_SDK_DEBUG else WIN_OPT_FLAGS?=/O2 /MT /Z7 endif diff --git a/native_client_sdk/src/tools/nacl_gcc.mk b/native_client_sdk/src/tools/nacl_gcc.mk index 51ed4b6..ea7d869 100644 --- a/native_client_sdk/src/tools/nacl_gcc.mk +++ b/native_client_sdk/src/tools/nacl_gcc.mk @@ -40,6 +40,15 @@ ARM_LINK?=$(TC_PATH)/$(OSNAME)_arm_$(TOOLCHAIN)/bin/arm-nacl-g++ ARM_LIB?=$(TC_PATH)/$(OSNAME)_arm_$(TOOLCHAIN)/bin/arm-nacl-ar +# Architecture-specific flags +X86_32_CFLAGS?=-DNACL_ARCH=x86_32 +X86_64_CFLAGS?=-DNACL_ARCH=x86_64 +ARM_CFLAGS?=-DNACL_ARCH=arm + +X86_32_CXXFLAGS?=-DNACL_ARCH=x86_32 +X86_64_CXXFLAGS?=-DNACL_ARCH=x86_64 +ARM_CXXFLAGS?=-DNACL_ARCH=arm + # # Compile Macro # @@ -49,29 +58,29 @@ ARM_LIB?=$(TC_PATH)/$(OSNAME)_arm_$(TOOLCHAIN)/bin/arm-nacl-ar define C_COMPILER_RULE -include $(call SRC_TO_DEP,$(1),_x86_32) $(call SRC_TO_OBJ,$(1),_x86_32): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC,$$@,$(X86_32_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS)) + $(call LOG,CC,$$@,$(X86_32_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(X86_32_CFLAGS)) -include $(call SRC_TO_DEP,$(1),_x86_64) $(call SRC_TO_OBJ,$(1),_x86_64): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC,$$@,$(X86_64_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS)) + $(call LOG,CC,$$@,$(X86_64_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(X86_64_CFLAGS)) -include $(call SRC_TO_DEP,$(1),_arm) $(call SRC_TO_OBJ,$(1),_arm): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CC,$$@,$(ARM_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS)) + $(call LOG,CC,$$@,$(ARM_CC) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CFLAGS) $(ARM_CFLAGS)) endef define CXX_COMPILER_RULE -include $(call SRC_TO_DEP,$(1),_x86_32) $(call SRC_TO_OBJ,$(1),_x86_32): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX,$$@,$(X86_32_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS)) + $(call LOG,CXX,$$@,$(X86_32_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(X86_32_CXXFLAGS)) -include $(call SRC_TO_DEP,$(1),_x86_64) $(call SRC_TO_OBJ,$(1),_x86_64): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX,$$@,$(X86_64_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS)) + $(call LOG,CXX,$$@,$(X86_64_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(X86_64_CXXFLAGS)) -include $(call SRC_TO_DEP,$(1),_arm) $(call SRC_TO_OBJ,$(1),_arm): $(1) $(TOP_MAKE) | $(dir $(call SRC_TO_OBJ,$(1)))dir.stamp - $(call LOG,CXX,_$$@,$(ARM_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS)) + $(call LOG,CXX,$$@,$(ARM_CXX) -o $$@ -c $$< $(POSIX_FLAGS) $(2) $(NACL_CXXFLAGS) $(ARM_CXXFLAGS)) endef |