├── .gitignore ├── LICENSE ├── README ├── SConstruct ├── chrome ├── _locales │ └── en │ │ └── messages.json ├── background.html ├── background.js ├── content_script.js ├── default_settings.js ├── icon-128.png ├── icon-16.png ├── icon-48.png ├── manifest.json ├── options.css ├── options.html └── options.js ├── icon.svg └── plugin ├── SConscript ├── command_template.cc ├── command_template.h ├── editor_type.cc ├── editor_type.h ├── emacs_instance.cc ├── emacs_instance.h ├── emacs_manager.cc ├── emacs_manager.h ├── emacs_object.cc ├── emacs_object.h ├── emacs_plugin.cc ├── event_thread.cc ├── event_thread.h ├── npapi-cxx ├── browser.cc ├── browser.h ├── plugin.cc ├── plugin.h ├── plugin_instance.cc ├── plugin_instance.h ├── scoped_npobject.h ├── script_object.cc ├── script_object.h ├── task.cc └── task.h ├── npapi-headers ├── npapi.h ├── npfunctions.h ├── npruntime.h └── nptypes.h ├── util.h └── xembed_container_plugin.cc /.gitignore: -------------------------------------------------------------------------------- 1 | *.os 2 | *.so 3 | 4 | .sconsign.dblite 5 | config.log 6 | 7 | chrome/LICENSE 8 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 David Benjamin 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | Embedded Emacs is a NPAPI plugin and Chrome extension pair that 2 | replaces textareas with embedded emacs. 3 | 4 | It uses the XEmbed-based NPAPI mode on Linux and emacs --parent-id to 5 | embed your system emacs binary into your browser. 6 | 7 | Known issues / TODO: 8 | - if web page modified CSS of textarea, emacs instance does not update 9 | - textareas do not update until emacs instance exits 10 | - buildsystem does not package crx 11 | - emacs 23.1 has a layout bug which can affect embedded-emacs. You may need to use 23.2 or later. 12 | -------------------------------------------------------------------------------- /SConstruct: -------------------------------------------------------------------------------- 1 | Decider('MD5-timestamp') 2 | 3 | env = Environment() 4 | 5 | variants = { 6 | 'i386': env.Clone(CCFLAGS="-m32", LINKFLAGS="-m32"), 7 | 'x86_64': env.Clone(CCFLAGS="-m64", LINKFLAGS="-m64"), 8 | } 9 | 10 | for name, variant_env in variants.items(): 11 | SConscript('plugin/SConscript', 12 | exports={'env': variant_env}, 13 | variant_dir='plugin/build-%s' % name, 14 | duplicate=0) 15 | 16 | env.Command('chrome/libembedded-emacs-launcher-%s.so' % name, 17 | 'plugin/build-%s/libembedded-emacs-launcher.so' % name, 18 | Copy("$TARGET", "$SOURCE")); 19 | env.Command('chrome/libembedded-emacs-container-%s.so' % name, 20 | 'plugin/build-%s/libembedded-emacs-container.so' % name, 21 | Copy("$TARGET", "$SOURCE")); 22 | 23 | env.Command('chrome/LICENSE', 'LICENSE', 24 | Copy("$TARGET", "$SOURCE")); 25 | -------------------------------------------------------------------------------- /chrome/_locales/en/messages.json: -------------------------------------------------------------------------------- 1 | { 2 | "EXT_NAME": { 3 | "message": "Embedded Emacs", 4 | "description": "Extension name." 5 | }, 6 | "EXT_DESCRIPTION": { 7 | "message": "Replaces textareas with an embedded Emacs.", 8 | "description": "Extension description." 9 | }, 10 | 11 | "TEXT_DIRECTION": { 12 | "message": "ltr", 13 | "description": "ltr or rtl, depending on text direction." 14 | }, 15 | 16 | "OPTIONS_TITLE": { 17 | "message": "Embedded Emacs Options", 18 | "description": "Title of the Options page." 19 | }, 20 | 21 | "EDITOR_SECTION_TITLE": { 22 | "message": "Text Editor", 23 | "description": "Title of the Text Editor section in Options." 24 | }, 25 | 26 | "PRESET_NAME_EMACS": { 27 | "message": "Emacs", 28 | "description": "Name of emacs preset command." 29 | }, 30 | "PRESET_NAME_GVIM": { 31 | "message": "gVim", 32 | "description": "Name of gVim preset command." 33 | }, 34 | "PRESET_NAME_CUSTOM": { 35 | "message": "Custom", 36 | "description": "Name of custom preset command." 37 | }, 38 | 39 | "EDITOR_COMMAND_LABEL": { 40 | "message": "Command to run:", 41 | "description": "Label next to the editor command in Options." 42 | }, 43 | 44 | "CUSTOM_COMMAND_INSTRUCTIONS": { 45 | "message": "To use a custom command, place a script titled embedded-text-editor somewhere in your PATH. The script takes two arguments, an X11 window ID and the path to a temporary file containing the initial text. When finished, the script should exit with the final text in that file. For example,", 46 | "description": "Instructions for setting up a custom command." 47 | }, 48 | 49 | "INVOCATION_SECTION_TITLE": { 50 | "message": "Invocation", 51 | "description": "Title of the Invocation section in Options." 52 | }, 53 | 54 | "TRIGGER_LIST_LABEL": { 55 | "message": "Embed into textareas on:", 56 | "description": "Label preceding list of configurable triggers." 57 | }, 58 | 59 | "TRIGGER_DESCRIPTION_ALT_X": { 60 | "message": "Pressing M-x (Alt-x)", 61 | "description": "Description of the Alt-x trigger." 62 | }, 63 | "TRIGGER_DESCRIPTION_DOUBLE_CLICK": { 64 | "message": "Double-click", 65 | "description": "Description of the double-click trigger." 66 | } 67 | } -------------------------------------------------------------------------------- /chrome/background.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /chrome/background.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | initDefaultSettings(); 6 | 7 | var launcher = document.getElementById('launcher'); 8 | 9 | chrome.extension.onRequest.addListener( 10 | function (request, sender, sendResponse) { 11 | if (request.type === 'get_config') { 12 | // TODO: send other config options when we get them. 13 | var enabled = launcher.hasOwnProperty('startEditor'); 14 | sendResponse({ 15 | enabled: enabled, 16 | triggerAltX: (localStorage['triggerAltX'] == 'true'), 17 | triggerDoubleClick: (localStorage['triggerDoubleClick'] == 'true') 18 | }); 19 | } else if (request.type === 'start_editor') { 20 | try { 21 | launcher.startEditor( 22 | request.windowId, localStorage['editorType'], request.text, 23 | function (contents, status) { sendResponse(contents);}); 24 | } catch (err) { 25 | // Don't leave the page hanging. 26 | sendResponse(request.text); 27 | throw err; 28 | } 29 | } else { 30 | console.log("WARNING: Unknown request type '" + 31 | request.type + "'"); 32 | console.log(request); 33 | console.log(sender); 34 | // Clear the request. 35 | sendResponse({}); 36 | } 37 | } 38 | ); 39 | -------------------------------------------------------------------------------- /chrome/content_script.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | function positioned(elem) { 6 | var position = window.getComputedStyle(elem).position; 7 | return (position === "absolute" || 8 | position === "relative" || 9 | position === "fixed"); 10 | } 11 | 12 | function hookTextArea(node, config) { 13 | function attachEmacs() { 14 | if (!node.parentNode) 15 | return; 16 | var container = document.createElement("div"); 17 | var embed = document.createElement("embed"); 18 | embed.type = "application/x-embedded-emacs-container"; 19 | embed.style.setProperty("width", "100%", "important"); 20 | embed.style.setProperty("height", "100%", "important"); 21 | embed.style.setProperty("padding", "0px", "important"); 22 | embed.style.setProperty("margin", "0px", "important"); 23 | // WebKit refuses to focus an embed element unless it has a tabIndex. 24 | embed.setAttribute("tabIndex", "0"); 25 | container.appendChild(embed); 26 | container.style.setProperty("border", "1px solid black", "important"); 27 | container.style.setProperty("padding", "0px", "important"); 28 | container.style.setProperty("margin", "0px", "important"); 29 | function relayout() { 30 | container.style.setProperty("width", node.offsetWidth + "px", 31 | "important"); 32 | container.style.setProperty("height", node.offsetHeight + "px", 33 | "important"); 34 | // Apparently offsetParent is a lie. 35 | var parent = node.offsetParent; 36 | var top = node.offsetTop; 37 | var left = node.offsetLeft; 38 | var body = node.ownerDocument.body; 39 | var docElem = node.ownerDocument.documentElement; 40 | while (parent && 41 | parent !== body && parent !== docElem && 42 | !positioned(parent)) { 43 | top += parent.offsetTop; 44 | left += parent.offsetLeft; 45 | parent = parent.offsetParent; 46 | } 47 | container.style.setProperty("top", top + "px", "important"); 48 | container.style.setProperty("left", left + "px", "important"); 49 | if (window.getComputedStyle(node).position === "fixed") { 50 | container.style.setProperty("position", "fixed", "important"); 51 | } else { 52 | container.style.setProperty("position", "absolute", "important"); 53 | } 54 | } 55 | relayout(); 56 | node.parentNode.insertBefore(container, node); 57 | 58 | // Make sure the plugin loaded. 59 | if (!embed.hasOwnProperty('windowId')) { 60 | console.log('Could not load container'); 61 | container.parentNode.removeChild(container); 62 | return; 63 | } 64 | 65 | window.addEventListener("resize", relayout); 66 | 67 | // FIXME: If another script decides to change this value 68 | // again, act accordingly. 69 | var oldVisibility = node.style.visibility; 70 | node.style.visibility = "hidden"; 71 | 72 | chrome.extension.sendRequest({ 73 | type: "start_editor", 74 | text: node.value, 75 | windowId: embed.windowId 76 | }, function (text) { 77 | window.removeEventListener("resize", relayout); 78 | 79 | node.value = text; 80 | node.style.visibility = oldVisibility; 81 | if (container.parentNode) 82 | container.parentNode.removeChild(container); 83 | }); 84 | 85 | // FIXME: This doesn't work. 86 | embed.focus(); 87 | } 88 | 89 | if (config.triggerAltX) 90 | // Apparently I don't get keypress for Alt-X. 91 | node.addEventListener('keydown', function (evt) { 92 | if ((evt.altKey || evt.metaKey) && 93 | !evt.ctrlKey && 94 | !evt.shiftKey && 95 | evt.keyCode === 88) { 96 | attachEmacs(); 97 | } 98 | }); 99 | if (config.triggerDoubleClick) 100 | node.addEventListener('dblclick', attachEmacs); 101 | } 102 | 103 | chrome.extension.sendRequest({ 104 | type: 'get_config' 105 | }, function (config) { 106 | if (config.enabled) { 107 | // Hook the current textareas. 108 | var textareas = document.getElementsByTagName("textarea"); 109 | for (var i = 0; i < textareas.length; i++) { 110 | hookTextArea(textareas[i], config); 111 | } 112 | 113 | // And hook any new ones that get created. 114 | document.body.addEventListener('DOMNodeInserted', function (ev) { 115 | if (ev.target.nodeType != 1) 116 | return; 117 | var textareas = ev.target.getElementsByTagName("textarea"); 118 | for (var i = 0; i < textareas.length; i++) { 119 | hookTextArea(textareas[i], config); 120 | } 121 | }); 122 | } 123 | }); 124 | -------------------------------------------------------------------------------- /chrome/default_settings.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Initialize default settings: 6 | function initDefaultSettings() { 7 | var defaultSettings = { 8 | editorType: "emacs", 9 | triggerAltX: true, 10 | triggerDoubleClick: false 11 | }; 12 | for (var k in defaultSettings) { 13 | if (localStorage[k] === undefined) 14 | localStorage[k] = defaultSettings[k]; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /chrome/icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidben/embedded-emacs/71561443d6aebba0d5043aaf0390d0749b98c232/chrome/icon-128.png -------------------------------------------------------------------------------- /chrome/icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidben/embedded-emacs/71561443d6aebba0d5043aaf0390d0749b98c232/chrome/icon-16.png -------------------------------------------------------------------------------- /chrome/icon-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidben/embedded-emacs/71561443d6aebba0d5043aaf0390d0749b98c232/chrome/icon-48.png -------------------------------------------------------------------------------- /chrome/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "manifest_version": 2, 3 | "name": "__MSG_EXT_NAME__", 4 | "version": "1.0.1", 5 | "default_locale": "en", 6 | "description": "__MSG_EXT_DESCRIPTION__", 7 | "permissions": [ 8 | ], 9 | "background": { 10 | "page": "background.html" 11 | }, 12 | "content_scripts": [ { 13 | "matches": [""], 14 | "js": ["content_script.js"], 15 | "run_at": "document_idle", 16 | "all_frames": true 17 | } ], 18 | "content_security_policy": "default-src 'self'", 19 | "homepage_url": "https://github.com/davidben/embedded-emacs", 20 | "icons": { 21 | "16": "icon-16.png", 22 | "48": "icon-48.png", 23 | "128": "icon-128.png" 24 | }, 25 | "offline_enabled": true, 26 | "options_page": "options.html", 27 | "plugins": [ 28 | { "path": "libembedded-emacs-launcher-i386.so" }, 29 | { "path": "libembedded-emacs-launcher-x86_64.so" }, 30 | { "path": "libembedded-emacs-container-i386.so", "public": true }, 31 | { "path": "libembedded-emacs-container-x86_64.so", "public": true } 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /chrome/options.css: -------------------------------------------------------------------------------- 1 | /* Look shamelessly borrowed from the Chromium tabbed settings page. */ 2 | body { 3 | direction: __MSG_TEXT_DIRECTION__; 4 | font-family: Arial, sans-serif; 5 | font-size: 84%; 6 | width: 600px; 7 | margin-left: auto; 8 | margin-right: auto; 9 | } 10 | h1 { 11 | color: #53637D; 12 | font-size: 200%; 13 | font-weight: normal; 14 | margin: 0px; 15 | padding-bottom: 4px; 16 | padding-top: 13px; 17 | border-bottom: 1px solid #eee; 18 | } 19 | input[type="text"] { 20 | border: 1px solid #AAA; 21 | padding: 3px; 22 | -webkit-border-radius: 2px; 23 | } 24 | 25 | button { 26 | -webkit-border-radius: 2px; 27 | -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1); 28 | -webkit-user-select: none; 29 | background: -webkit-linear-gradient(#fafafa, #f4f4f4 40%, #e5e5e5); 30 | border: 1px solid #aaa; 31 | color: #444; 32 | font-size: inherit; 33 | margin-bottom: 0px; 34 | min-width: 4em; 35 | padding: 3px 12px 3px 12px; 36 | } 37 | 38 | button:hover { 39 | -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.2); 40 | background: #ebebeb -webkit-linear-gradient(#fefefe, #f8f8f8 40%, #e9e9e9); 41 | border-color: #999; 42 | color: #222; 43 | } 44 | 45 | button:active { 46 | -webkit-box-shadow: inset 0px 1px 3px rgba(0, 0, 0, 0.2); 47 | background: #ebebeb -webkit-linear-gradient(#f4f4f4, #efefef 40%, #dcdcdc); 48 | color: #333; 49 | } 50 | 51 | section { 52 | border-bottom: 1px solid #eee; 53 | display: -webkit-box; 54 | -webkit-box-orient: horizontal; 55 | margin-top: 1em; 56 | margin-bottom: 1em; 57 | padding-bottom: 1.5em; 58 | } 59 | section:last-child { 60 | border-bottom: none; 61 | } 62 | section > h2 { 63 | width: 150px; 64 | vertical-align: middle; 65 | margin: 0px; 66 | font-weight: bold; 67 | font-size: 100%; 68 | padding-top: 2px; 69 | } 70 | section > div { 71 | -webkit-box-flex: 1; 72 | } 73 | section > div label { 74 | display: block; 75 | margin: 3px 0px; 76 | } 77 | section > div h3 { 78 | font-size: 100%; 79 | font-weight: bold; 80 | margin: 0px; 81 | padding-top: 2px; 82 | } 83 | 84 | .editorOption > kbd { 85 | float: right; 86 | } 87 | -------------------------------------------------------------------------------- /chrome/options.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

11 | 12 |
13 |

14 |
15 |

16 | 17 | 22 | 23 | 28 | 29 | 34 |

35 | 36 |
37 | 38 |
#!/bin/sh
39 | WINDOW="$1"
40 | FILE="$2"
41 | exec urxvt -embed "$WINDOW" -e nano "$FILE"
42 | 
43 |
44 |
45 |
46 | 47 |
48 |

49 |
50 | 51 | 55 | 59 |
60 |
61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /chrome/options.js: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | // Doesn't hurt. Not sure if relying on the background page can race. 6 | initDefaultSettings(); 7 | 8 | // Borrow Chromium WebUI-style i18n handling, or at least something 9 | // similar. 10 | function localizeElements() { 11 | var elements = document.querySelectorAll("[i18n-content]"); 12 | for (var i = 0; i < elements.length; i++) { 13 | var element = elements[i]; 14 | var key = element.getAttribute("i18n-content"); 15 | // Ick. I'd prefer textContent, but there are tags in 16 | // places. 17 | element.innerHTML = chrome.i18n.getMessage(key); 18 | } 19 | } 20 | 21 | function setup() { 22 | localizeElements(); 23 | loadOptions(); 24 | updateInstructions(); 25 | 26 | // Hook up listeners. 27 | var editorOptions = document.getElementsByName("editor"); 28 | for (var i = 0; i < editorOptions.length; i++) { 29 | editorOptions[i].addEventListener("change", saveOptions); 30 | } 31 | document.getElementById("triggerAltX").addEventListener("change", saveOptions); 32 | document.getElementById("triggerDoubleClick").addEventListener("change", saveOptions); 33 | } 34 | 35 | function updateInstructions() { 36 | var customInstructions = document.getElementById("customInstructions"); 37 | var editorOptionCustom = document.getElementById("editorOptionCustom"); 38 | customInstructions.hidden = !editorOptionCustom.checked; 39 | } 40 | 41 | function loadOptions() { 42 | var editorOptions = document.getElementsByName("editor"); 43 | for (var i = 0; i < editorOptions.length; i++) { 44 | editorOptions[i].checked = (editorOptions[i].value == localStorage["editorType"]); 45 | } 46 | 47 | document.getElementById("triggerAltX").checked = (localStorage["triggerAltX"] == "true"); 48 | document.getElementById("triggerDoubleClick").checked = (localStorage["triggerDoubleClick"] == "true"); 49 | } 50 | 51 | function saveOptions() { 52 | var editorOptions = document.getElementsByName("editor"); 53 | for (var i = 0; i < editorOptions.length; i++) { 54 | if (editorOptions[i].checked) 55 | localStorage["editorType"] = editorOptions[i].value; 56 | } 57 | 58 | localStorage["triggerAltX"] = (document.getElementById("triggerAltX").checked ? "true" : "false"); 59 | localStorage["triggerDoubleClick"] = (document.getElementById("triggerDoubleClick").checked ? "true" : "false"); 60 | 61 | updateInstructions(); 62 | } 63 | 64 | window.addEventListener("load", setup); 65 | -------------------------------------------------------------------------------- /icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 22 | 24 | 26 | 30 | 34 | 35 | 37 | 41 | 45 | 46 | 48 | 52 | 56 | 60 | 61 | 63 | 67 | 71 | 75 | 76 | 78 | 82 | 86 | 90 | 91 | 93 | 97 | 101 | 105 | 106 | 108 | 112 | 116 | 120 | 121 | 132 | 134 | 138 | 142 | 146 | 147 | 158 | 160 | 164 | 168 | 172 | 173 | 184 | 186 | 190 | 194 | 198 | 199 | 210 | 212 | 216 | 220 | 224 | 225 | 236 | 238 | 242 | 246 | 250 | 251 | 262 | 264 | 268 | 272 | 276 | 277 | 288 | 291 | 295 | 296 | 307 | 310 | 315 | 316 | 326 | 329 | 333 | 334 | 337 | 342 | 343 | 354 | 357 | 361 | 362 | 363 | 384 | 391 | 395 | 399 | 403 | 407 | 408 | 410 | 411 | 413 | image/svg+xml 414 | 416 | 417 | 418 | 419 | 420 | 425 | 430 | 438 | 445 | 452 | 459 | 466 | 470 | 473 | 478 | 479 | 486 | 491 | 496 | 501 | 506 | 507 | 513 | 522 | 523 | 524 | -------------------------------------------------------------------------------- /plugin/SConscript: -------------------------------------------------------------------------------- 1 | Import("env") 2 | def CheckPKGConfig(context, version): 3 | context.Message( 'Checking for pkg-config... ' ) 4 | ret = context.TryAction('pkg-config --atleast-pkgconfig-version=%s' % version)[0] 5 | context.Result( ret ) 6 | return ret 7 | 8 | def CheckPKG(context, name): 9 | context.Message( 'Checking for %s... ' % name ) 10 | ret = context.TryAction('pkg-config --exists \'%s\'' % name)[0] 11 | context.Result( ret ) 12 | return ret 13 | 14 | conf = Configure(env, custom_tests = { 'CheckPKGConfig' : CheckPKGConfig, 15 | 'CheckPKG' : CheckPKG }) 16 | if not conf.CheckPKGConfig('0.15.0'): 17 | print 'pkg-config >= 0.15.0 not found.' 18 | Exit(1) 19 | if not conf.CheckPKG('glib-2.0'): 20 | print 'GLib not found.' 21 | Exit(1) 22 | if not conf.CheckPKG('gthread-2.0'): 23 | print 'GLib not found.' 24 | Exit(1) 25 | if not conf.CheckPKG('gtk+-2.0'): 26 | print 'GTK+ not found.' 27 | Exit(1) 28 | env = conf.Finish() 29 | 30 | # Allow includes relative to the top-level directory. 31 | env.Append(CPPPATH=['.']) 32 | # Hide symbols unless told otherwise. 33 | env.Append(CCFLAGS=['-fvisibility=hidden', '-fvisibility-inlines-hidden', '-Wall']) 34 | 35 | env.ParseConfig('pkg-config --cflags --libs glib-2.0') 36 | env.ParseConfig('pkg-config --cflags --libs gthread-2.0') 37 | env.ParseConfig('pkg-config --cflags --libs gtk+-2.0') 38 | 39 | base_files = ['npapi-cxx/browser.cc', 40 | 'npapi-cxx/plugin.cc', 41 | 'npapi-cxx/plugin_instance.cc', 42 | 'npapi-cxx/script_object.cc', 43 | 'npapi-cxx/task.cc', 44 | ] 45 | 46 | env.SharedLibrary('embedded-emacs-launcher', base_files + \ 47 | ['editor_type.cc', 48 | 'emacs_instance.cc', 49 | 'emacs_manager.cc', 50 | 'emacs_object.cc', 51 | 'emacs_plugin.cc', 52 | 'event_thread.cc', 53 | ]) 54 | 55 | env.SharedLibrary('embedded-emacs-container', base_files + \ 56 | ['xembed_container_plugin.cc']) 57 | -------------------------------------------------------------------------------- /plugin/command_template.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "command_template.h" 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | namespace { 12 | 13 | bool FindVariable(const std::string& pattern, 14 | size_t pos, 15 | std::string *varname, 16 | size_t *endp, 17 | std::string *error) { 18 | assert(pattern[pos] == '$'); 19 | if (pos+1 >= pattern.size()) { 20 | *error = "expected variable name after '$'"; 21 | return false; 22 | } 23 | if (pattern[pos+1] == '{') { 24 | // Look for a '}'. 25 | size_t end = pattern.find('}', pos+1); 26 | if (end == std::string::npos) { 27 | *error = "expected '}' after '${'"; 28 | return false; 29 | } 30 | *endp = end+1; 31 | *varname = pattern.substr(pos+2, (end+1) - (pos+2) - 1); 32 | return true; 33 | } else { 34 | // Look for whitespace. 35 | size_t end; 36 | for (end = pos+1; end < pattern.size(); end++) { 37 | if (!g_ascii_isalnum(pattern[end]) && pattern[end] != '_') 38 | break; 39 | } 40 | *endp = end; 41 | *varname = pattern.substr(pos+1, end - (pos+1)); 42 | return true; 43 | } 44 | }; 45 | 46 | } // namespace 47 | 48 | namespace command_template { 49 | 50 | bool ApplyTemplate(const std::string& pattern, 51 | const Environment& env, 52 | std::vector& argv, 53 | std::string *error) { 54 | enum State { 55 | NONE, 56 | SINGLE_QUOTE, 57 | DOUBLE_QUOTE, 58 | PARAM_END, 59 | }; 60 | State state = NONE; 61 | std::string cur_param; 62 | for (size_t i = 0; i < pattern.size(); i++) { 63 | if (state == PARAM_END) { 64 | // Finish the current parameter. 65 | if (g_ascii_isspace(pattern[i])) 66 | continue; 67 | argv.push_back(cur_param); 68 | cur_param.clear(); 69 | state = NONE; 70 | } 71 | 72 | if (state == SINGLE_QUOTE) { 73 | // Only magical character in single quotes is another 74 | // single quote. 75 | if (pattern[i] == '\'') { 76 | state = NONE; 77 | continue; 78 | } 79 | } else { 80 | if (state == NONE) { 81 | // Handle the bits where double quotes affect things. 82 | // (Okay, fine. There's the obnoxious "$VAR" thing, 83 | // but I'm not implementing that. None of that makes 84 | // sense for $PATH and $WINDOW.) 85 | if (pattern[i] == '\'') { 86 | state = SINGLE_QUOTE; 87 | continue; 88 | } 89 | if (pattern[i] == '\"') { 90 | state = DOUBLE_QUOTE; 91 | continue; 92 | } 93 | if (g_ascii_isspace(pattern[i])) { 94 | state = PARAM_END; 95 | continue; 96 | } 97 | } else if (state == DOUBLE_QUOTE) { 98 | if (pattern[i] == '\"') { 99 | state = NONE; 100 | continue; 101 | } 102 | } 103 | if (pattern[i] == '$') { 104 | // Take care of variables. 105 | std::string varname; 106 | size_t end; 107 | if (!FindVariable(pattern, i, &varname, &end, error)) { 108 | return false; 109 | } 110 | Environment::const_iterator iter = env.find(varname); 111 | if (iter != env.end()) 112 | cur_param += iter->second; 113 | i = end - 1; 114 | continue; 115 | } 116 | // Backslashes are somewhat more complicated than this, 117 | // but whatever. Honestly, if you want something fancy, 118 | // you should write a wrapper shell script. 119 | if (pattern[i] == '\\') { 120 | if (i + 1 >= pattern.size()) { 121 | *error = "expected character after \\"; 122 | return false; 123 | } 124 | cur_param += pattern[i+1]; 125 | i++; 126 | continue; 127 | } 128 | } 129 | // Okay, there's nothing interesting to be done. Just append 130 | // the character. 131 | cur_param += pattern[i]; 132 | } 133 | 134 | if (state == SINGLE_QUOTE) { 135 | *error = "expected '"; 136 | return false; 137 | } 138 | if (state == DOUBLE_QUOTE) { 139 | *error = "expected \""; 140 | return false; 141 | } 142 | argv.push_back(cur_param); 143 | 144 | return true; 145 | } 146 | 147 | char** StringVectorToArgv(const std::vector& vec) { 148 | char **argv = g_new(char*, vec.size() + 1); 149 | for (size_t i = 0; i < vec.size(); i++) { 150 | argv[i] = g_strdup(vec[i].c_str()); 151 | } 152 | argv[vec.size()] = NULL; 153 | return argv; 154 | } 155 | 156 | } // namespace command_template 157 | -------------------------------------------------------------------------------- /plugin/command_template.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_COMMAND_TEMPLATE_H_ 6 | #define INCLUDED_COMMAND_TEMPLATE_H_ 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | namespace command_template { 13 | 14 | typedef std::tr1::unordered_map Environment; 15 | 16 | bool ApplyTemplate(const std::string& pattern, 17 | const Environment& env, 18 | std::vector& argv, 19 | std::string *error); 20 | 21 | char** StringVectorToArgv(const std::vector& vec); 22 | 23 | } // namespace command_template 24 | 25 | #endif // INCLUDED_COMMAND_TEMPLATE_H_ 26 | -------------------------------------------------------------------------------- /plugin/editor_type.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "editor_type.h" 6 | 7 | #include 8 | #include 9 | 10 | #include 11 | 12 | namespace { 13 | 14 | std::string LongToString(long n) { 15 | std::stringstream ss; 16 | ss << n; 17 | return ss.str(); 18 | } 19 | 20 | } // namespace 21 | 22 | EditorType StringToEditorType(const std::string& editor) { 23 | if (editor == "emacs") { 24 | return EDITOR_TYPE_EMACS; 25 | } else if (editor == "gvim") { 26 | return EDITOR_TYPE_GVIM; 27 | } else if (editor == "custom") { 28 | return EDITOR_TYPE_CUSTOM; 29 | } else { 30 | return EDITOR_TYPE_INVALID; 31 | } 32 | } 33 | 34 | char** GetEditorCommandArgv(EditorType editor, 35 | long window_id, 36 | const std::string& tmpfile_path) { 37 | std::string window_str = LongToString(window_id); 38 | switch (editor) { 39 | case EDITOR_TYPE_EMACS: { 40 | // emacs --parent-id $WINDOW -- $PATH 41 | char **argv = g_new(char*, 6); 42 | argv[0] = g_strdup("emacs"); 43 | argv[1] = g_strdup("--parent-id"); 44 | argv[2] = g_strdup(window_str.c_str()); 45 | argv[3] = g_strdup("--"); 46 | argv[4] = g_strdup(tmpfile_path.c_str()); 47 | argv[5] = NULL; 48 | return argv; 49 | } 50 | case EDITOR_TYPE_GVIM: { 51 | // gvim --nofork --socketid $WINDOW -- $PATH 52 | char **argv = g_new(char*, 7); 53 | argv[0] = g_strdup("gvim"); 54 | argv[1] = g_strdup("--nofork"); 55 | argv[2] = g_strdup("--socketid"); 56 | argv[3] = g_strdup(window_str.c_str()); 57 | argv[4] = g_strdup("--"); 58 | argv[5] = g_strdup(tmpfile_path.c_str()); 59 | argv[6] = NULL; 60 | return argv; 61 | } 62 | case EDITOR_TYPE_CUSTOM: { 63 | // embedded-text-editor $WINDOW $PATH 64 | char **argv = g_new(char*, 4); 65 | argv[0] = g_strdup("embedded-text-editor"); 66 | argv[1] = g_strdup(window_str.c_str()); 67 | argv[2] = g_strdup(tmpfile_path.c_str()); 68 | argv[3] = NULL; 69 | return argv; 70 | } 71 | default: 72 | fprintf(stderr, "Invalid EditorType (%d)\n", editor); 73 | return NULL; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /plugin/editor_type.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_EDITOR_TYPE_H_ 6 | #define INCLUDED_EDITOR_TYPE_H_ 7 | 8 | #include 9 | 10 | enum EditorType { 11 | EDITOR_TYPE_INVALID, 12 | EDITOR_TYPE_EMACS, 13 | EDITOR_TYPE_GVIM, 14 | EDITOR_TYPE_CUSTOM, 15 | }; 16 | 17 | EditorType StringToEditorType(const std::string& editor); 18 | 19 | char** GetEditorCommandArgv(EditorType editor, 20 | long window_id, 21 | const std::string& tmpfile_path); 22 | 23 | #endif // INCLUDED_EDITOR_TYPE_H_ 24 | -------------------------------------------------------------------------------- /plugin/emacs_instance.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "emacs_instance.h" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include "emacs_manager.h" 13 | #include "npapi-cxx/browser.h" 14 | 15 | EmacsInstance::EmacsInstance(EmacsManager* parent, 16 | long window_id, 17 | EditorType editor, 18 | const std::string& initial_text, 19 | NPObject *callback) 20 | : parent_(parent), 21 | child_pid_(0), 22 | job_id_(0), 23 | plug_(NULL) { 24 | if (StartEditor(window_id, editor, initial_text)) { 25 | callback_.reset(callback); 26 | } 27 | } 28 | 29 | EmacsInstance::~EmacsInstance() { 30 | if (!temp_file_.empty()) { 31 | if (unlink(temp_file_.c_str()) < 0) 32 | perror("unlink"); 33 | } 34 | 35 | if (plug_) 36 | gtk_widget_destroy(plug_); 37 | } 38 | 39 | bool EmacsInstance::StartEditor(long window_id, 40 | EditorType editor, 41 | const std::string& initial_text) { 42 | GError *gerror = NULL; 43 | 44 | if (!window_id) { 45 | fprintf(stderr, "Error: Invalid window.\n"); 46 | error_ = "invalid window"; 47 | return false; 48 | } 49 | 50 | // FIXME: Do file io on a dedicated thread. 51 | char *name = NULL; 52 | int fd = g_file_open_tmp(".embedded-emacs.XXXXXX", &name, &gerror); 53 | if (fd < 0) { 54 | error_ = "failed to create temporary file: "; 55 | error_ += gerror->message; 56 | g_error_free(gerror); 57 | return false; 58 | } 59 | temp_file_.assign(name); 60 | g_free(name); 61 | FILE* file = fdopen(fd, "w"); 62 | if (!file) { 63 | close(fd); 64 | // FIXME: strerror_r and UNIX are a trainwreck. 65 | error_ = "failed to fdopen"; 66 | return false; 67 | } 68 | fwrite(initial_text.c_str(), initial_text.size(), 1, file); 69 | fclose(file); 70 | 71 | // HACK: Wrap in socket so we can grab the focus. Remove this code 72 | // when http://crbug.com/27868 is fixed. 73 | plug_ = gtk_plug_new(window_id); 74 | GtkWidget* socket = gtk_socket_new(); 75 | gtk_container_add(GTK_CONTAINER(plug_), socket); 76 | gtk_widget_show_all(plug_); 77 | gtk_widget_set_can_focus(socket, TRUE); 78 | gtk_widget_grab_focus(socket); 79 | gtk_widget_set_can_focus(socket, FALSE); 80 | 81 | char **argv = GetEditorCommandArgv( 82 | editor, gtk_socket_get_id(GTK_SOCKET(socket)), temp_file_); 83 | GPid pid; 84 | if (!g_spawn_async(NULL, argv, NULL, 85 | static_cast( 86 | G_SPAWN_DO_NOT_REAP_CHILD | G_SPAWN_SEARCH_PATH), 87 | NULL, NULL, &pid, &gerror)) { 88 | g_strfreev(argv); 89 | error_ = std::string("failed to spawn child process: ") + 90 | gerror->message; 91 | g_error_free(gerror); 92 | return false; 93 | } 94 | g_strfreev(argv); 95 | 96 | child_pid_ = pid; 97 | return true; 98 | } 99 | 100 | void EmacsInstance::ChildExited(GPid pid, int status) { 101 | if (child_pid_ != pid) { 102 | fprintf(stderr, "WARNING: Unexpected child exit (pid %d)\n", pid); 103 | return; 104 | } 105 | if (!callback_.get()) { 106 | fprintf(stderr, "WARNING: No callback defined.\n"); 107 | return; 108 | } 109 | if (temp_file_.empty()) { 110 | fprintf(stderr, "ERROR: No temporary file???\n"); 111 | return; 112 | } 113 | 114 | NPVariant args[2]; 115 | INT32_TO_NPVARIANT(status, args[1]); 116 | 117 | // Get the file contents. 118 | gchar *contents; 119 | gsize length; 120 | GError *gerror; 121 | if (g_file_get_contents(temp_file_.c_str(), 122 | &contents, &length, 123 | &gerror)) { 124 | // Copy to NPN_MemAlloc-compatible buffer. 125 | NPUTF8 *np_contents = static_cast(NPN_MemAlloc(length)); 126 | memcpy(np_contents, contents, length); 127 | g_free(contents); 128 | STRINGN_TO_NPVARIANT(np_contents, length, args[0]); 129 | } else { 130 | fprintf(stderr, "Error: Failed read file: %s\n", gerror->message); 131 | g_error_free(gerror); 132 | NULL_TO_NPVARIANT(args[0]); 133 | } 134 | 135 | NPVariant result; 136 | NPN_InvokeDefault(parent_->npp(), callback_.get(), args, 2, &result); 137 | NPN_ReleaseVariantValue(&args[0]); 138 | NPN_ReleaseVariantValue(&args[1]); 139 | NPN_ReleaseVariantValue(&result); 140 | } 141 | -------------------------------------------------------------------------------- /plugin/emacs_instance.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_EMACS_INSTANCE_H_ 6 | #define INCLUDED_EMACS_INSTANCE_H_ 7 | 8 | #include 9 | 10 | #include 11 | 12 | #include "editor_type.h" 13 | #include "npapi-cxx/browser.h" 14 | #include "npapi-cxx/scoped_npobject.h" 15 | #include "util.h" 16 | 17 | class EmacsManager; 18 | G_FORWARD_DECLARE(GtkWidget); 19 | typedef struct NPObject NPObject; 20 | 21 | class EmacsInstance { 22 | public: 23 | EmacsInstance(EmacsManager* parent, 24 | long window_id, 25 | EditorType editor, 26 | const std::string& initial_text, 27 | NPObject *callback); 28 | ~EmacsInstance(); 29 | 30 | // Returns 0 if the launch failed. 31 | GPid pid() const { return child_pid_; } 32 | const std::string& error() const { return error_; } 33 | 34 | int job_id() const { return job_id_; } 35 | void set_job_id(int job_id) { job_id_ = job_id; } 36 | 37 | EmacsManager* manager() const { return parent_; } 38 | 39 | void ChildExited(GPid pid, int status); 40 | private: 41 | bool StartEditor(long window_id, 42 | EditorType editor, 43 | const std::string& initial_text); 44 | 45 | EmacsManager *parent_; 46 | std::string error_; 47 | GPid child_pid_; 48 | npapi::scoped_npobject callback_; 49 | int job_id_; 50 | GtkWidget* plug_; 51 | 52 | std::string temp_file_; 53 | 54 | DISALLOW_COPY_AND_ASSIGN(EmacsInstance); 55 | }; 56 | 57 | #endif // INCLUDED_EMACS_INSTANCE_H_ 58 | -------------------------------------------------------------------------------- /plugin/emacs_manager.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "emacs_manager.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "emacs_instance.h" 11 | #include "emacs_object.h" 12 | #include "event_thread.h" 13 | #include "npapi-cxx/browser.h" 14 | #include "npapi-cxx/task.h" 15 | #include "npapi-headers/npruntime.h" 16 | 17 | namespace { 18 | 19 | class ChildExitedTask : public npapi::Task { 20 | public: 21 | ChildExitedTask(EmacsInstance *emacs, GPid pid, int status) 22 | : emacs_(emacs), 23 | pid_(pid), 24 | status_(status) { 25 | } 26 | 27 | virtual void Run(npapi::PluginInstance* manager) { 28 | static_cast(manager)->ChildExited(emacs_, pid_, status_); 29 | } 30 | 31 | private: 32 | EmacsInstance* emacs_; 33 | GPid pid_; 34 | int status_; 35 | 36 | DISALLOW_COPY_AND_ASSIGN(ChildExitedTask); 37 | }; 38 | 39 | void ChildExitThunk(GPid pid, int status, gpointer data) { 40 | EmacsInstance* instance = static_cast(data); 41 | instance->manager()->PostTask( 42 | new ChildExitedTask(instance, pid, status)); 43 | } 44 | 45 | } // namespace 46 | 47 | EmacsManager::EmacsManager(NPP npp) 48 | : npapi::PluginInstance(npp), 49 | next_job_id_(1), 50 | event_thread_(NULL) { 51 | // Set window-less so Chromium doesn't try to XEmbed us. 52 | NPN_SetValue(npp, NPPVpluginWindowBool, NULL); 53 | } 54 | 55 | EmacsManager::~EmacsManager() { 56 | // Clean up all remaining EmacsInstances 57 | typedef std::tr1::unordered_map::iterator iter_t; 58 | for (iter_t i = emacs_jobs_.begin(), end = emacs_jobs_.end(); 59 | i != end; 60 | ++i) { 61 | delete i->second; 62 | } 63 | 64 | delete event_thread_; 65 | } 66 | 67 | int EmacsManager::StartEditor(long window_id, 68 | EditorType editor, 69 | const std::string& initial_text, 70 | NPObject *callback, 71 | std::string *error) { 72 | EmacsInstance *instance = 73 | new EmacsInstance(this, window_id, editor, initial_text, callback); 74 | if (!instance->pid()) { 75 | *error = instance->error(); 76 | fprintf(stderr, "Error: %s\n", error->c_str()); 77 | delete instance; 78 | return 0; 79 | } 80 | int job_id = next_job_id_++; 81 | instance->set_job_id(job_id); 82 | emacs_jobs_[job_id] = instance; 83 | 84 | // Watch the pid. 85 | if (!event_thread_) 86 | event_thread_ = new EventThread; 87 | GSource* source = g_child_watch_source_new(instance->pid()); 88 | g_source_set_callback( 89 | source, reinterpret_cast(ChildExitThunk), instance, NULL); 90 | g_source_attach(source, event_thread_->main_context()); 91 | g_source_unref(source); 92 | 93 | return job_id; 94 | } 95 | 96 | void EmacsManager::ChildExited(EmacsInstance* instance, GPid pid, int status) { 97 | instance->ChildExited(pid, status); 98 | emacs_jobs_.erase(instance->job_id()); 99 | } 100 | 101 | NPError EmacsManager::GetValue(NPPVariable variable, void* value) { 102 | NPError err = NPERR_NO_ERROR; 103 | switch (variable) { 104 | case NPPVpluginScriptableNPObject: { 105 | if (!script_object_.get()) { 106 | script_object_.reset(EmacsObject::Create(npp())); 107 | } 108 | *reinterpret_cast(value) = 109 | static_cast(script_object_.get()); 110 | break; 111 | } 112 | default: 113 | err = PluginInstance::GetValue(variable, value); 114 | } 115 | return err; 116 | } 117 | -------------------------------------------------------------------------------- /plugin/emacs_manager.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_EMACS_MANAGER_H_ 6 | #define INCLUDED_EMACS_MANAGER_H_ 7 | 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include "editor_type.h" 14 | #include "npapi-cxx/plugin_instance.h" 15 | #include "npapi-cxx/scoped_npobject.h" 16 | #include "util.h" 17 | 18 | class EmacsInstance; 19 | class EmacsObject; 20 | class EventThread; 21 | typedef struct NPObject NPObject; 22 | 23 | // There really should only ever be one instance of this class. 24 | class EmacsManager : public npapi::PluginInstance { 25 | public: 26 | EmacsManager(NPP npp); 27 | ~EmacsManager(); 28 | 29 | int StartEditor(long window_id, 30 | EditorType editor, 31 | const std::string& initial_text, 32 | NPObject *callback, 33 | std::string *error); 34 | // TODO: Implement some way to cancel a job? 35 | 36 | void ChildExited(EmacsInstance* instance, GPid pid, int status); 37 | 38 | NPError GetValue(NPPVariable variable, void* value); 39 | private: 40 | int next_job_id_; 41 | npapi::scoped_npobject script_object_; 42 | std::tr1::unordered_map emacs_jobs_; 43 | 44 | EventThread *event_thread_; 45 | 46 | DISALLOW_COPY_AND_ASSIGN(EmacsManager); 47 | }; 48 | 49 | #endif // INCLUDED_EMACS_MANAGER_H_ 50 | -------------------------------------------------------------------------------- /plugin/emacs_object.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2012 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "emacs_object.h" 6 | 7 | #include "editor_type.h" 8 | #include "emacs_manager.h" 9 | 10 | EmacsObject::EmacsObject(NPP npp) : npapi::ScriptObject(npp) { 11 | } 12 | 13 | EmacsObject::~EmacsObject() { 14 | } 15 | 16 | EmacsManager* EmacsObject::emacs_manager() { 17 | return static_cast(plugin_instance()); 18 | } 19 | 20 | bool EmacsObject::HasMethod(NPIdentifier name) { 21 | return (name == NPN_GetStringIdentifier("startEditor")); 22 | } 23 | 24 | bool EmacsObject::Invoke(NPIdentifier name, 25 | const NPVariant *args, 26 | uint32_t arg_count, 27 | NPVariant *result) { 28 | EmacsManager* emacs = emacs_manager(); 29 | if (!emacs) { 30 | // TODO: raise an exception if the emacs is missing? 31 | VOID_TO_NPVARIANT(*result); 32 | return true; 33 | } 34 | if (name == NPN_GetStringIdentifier("startEditor")) { 35 | // Argument count. 36 | if (arg_count < 4) { 37 | NPN_SetException(this, "startEditor takes four arguments"); 38 | return true; 39 | } 40 | 41 | // Window ID. 42 | int window_id; 43 | if (NPVARIANT_IS_INT32(args[0])) { 44 | window_id = NPVARIANT_TO_INT32(args[0]); 45 | } else if (NPVARIANT_IS_DOUBLE(args[0])) { 46 | // WHAT??? 47 | window_id = static_cast(NPVARIANT_TO_DOUBLE(args[0])); 48 | } else { 49 | NPN_SetException(this, "window argument is not a number"); 50 | return true; 51 | } 52 | 53 | // Editor type. 54 | if (!NPVARIANT_IS_STRING(args[1])) { 55 | NPN_SetException(this, "editor argument is not a string"); 56 | return true; 57 | } 58 | std::string editor_string = std::string( 59 | NPVARIANT_TO_STRING(args[1]).UTF8Characters, 60 | NPVARIANT_TO_STRING(args[1]).UTF8Length); 61 | EditorType editor = StringToEditorType(editor_string); 62 | if (editor == EDITOR_TYPE_INVALID) { 63 | NPN_SetException(this, "invalid editor type"); 64 | return true; 65 | } 66 | 67 | // Initial text. 68 | if (!NPVARIANT_IS_STRING(args[2])) { 69 | NPN_SetException(this, "text argument is not a string"); 70 | return true; 71 | } 72 | if (!NPVARIANT_IS_OBJECT(args[3])) { 73 | NPN_SetException(this, "callback argument is not an object"); 74 | return true; 75 | } 76 | std::string initial_text = std::string( 77 | NPVARIANT_TO_STRING(args[2]).UTF8Characters, 78 | NPVARIANT_TO_STRING(args[2]).UTF8Length); 79 | 80 | // Finally run the function. 81 | std::string error; 82 | int job_id = emacs->StartEditor( 83 | window_id, 84 | editor, 85 | initial_text, 86 | NPVARIANT_TO_OBJECT(args[3]), 87 | &error); 88 | if (job_id == 0) 89 | NPN_SetException(this, error.c_str()); 90 | INT32_TO_NPVARIANT(job_id, *result); 91 | return true; 92 | } 93 | 94 | return false; 95 | } 96 | 97 | bool EmacsObject::Enumerate(NPIdentifier **identifiers, 98 | uint32_t *identifier_count) { 99 | const int kPropertyCount = 1; 100 | NPIdentifier* properties = static_cast( 101 | NPN_MemAlloc(sizeof(NPIdentifier) * kPropertyCount)); 102 | if (!properties) return false; 103 | 104 | properties[0] = NPN_GetStringIdentifier("startEditor"); 105 | 106 | *identifiers = properties; 107 | *identifier_count = kPropertyCount; 108 | return true; 109 | } 110 | -------------------------------------------------------------------------------- /plugin/emacs_object.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_EMACS_OBJECT_H_ 6 | #define INCLUDED_EMACS_OBJECT_H_ 7 | 8 | #include "npapi-cxx/script_object.h" 9 | 10 | class EmacsManager; 11 | 12 | class EmacsObject : public npapi::ScriptObject { 13 | public: 14 | bool HasMethod(NPIdentifier name); 15 | bool Invoke(NPIdentifier name, 16 | const NPVariant *args, 17 | uint32_t arg_count, 18 | NPVariant *result); 19 | bool Enumerate(NPIdentifier **identifiers, uint32_t *identifier_count); 20 | 21 | private: 22 | friend class npapi::ScriptObject; 23 | EmacsObject(NPP npp); 24 | ~EmacsObject(); 25 | 26 | EmacsManager* emacs_manager(); 27 | 28 | DISALLOW_COPY_AND_ASSIGN(EmacsObject); 29 | }; 30 | 31 | #endif // INCLUDED_EMACS_OBJECT_H_ 32 | -------------------------------------------------------------------------------- /plugin/emacs_plugin.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "emacs_manager.h" 6 | #include "npapi-cxx/browser.h" 7 | #include "npapi-cxx/plugin.h" 8 | 9 | namespace { 10 | 11 | class EmacsPlugin : public npapi::Plugin { 12 | public: 13 | NPError Init() { 14 | int major_version, minor_version; 15 | NPN_Version(NULL, NULL, &major_version, &minor_version); 16 | 17 | // Require NPRuntime. 18 | if (minor_version < NPVERS_HAS_NPRUNTIME_SCRIPTING) 19 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 20 | 21 | // Require sane threading. 22 | if (minor_version < NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL) 23 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 24 | 25 | // Require XEmbed support. 26 | int has_xembed = false; 27 | NPError err = NPN_GetValue(NULL, NPNVSupportsXEmbedBool, &has_xembed); 28 | if (err != NPERR_NO_ERROR || !has_xembed) 29 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 30 | 31 | return NPERR_NO_ERROR; 32 | } 33 | 34 | const char* GetMIMEDescription() { 35 | return "application/x-embedded-emacs-launcher::Embed emacs with NPAPI"; 36 | } 37 | 38 | NPError GetValue(NPPVariable variable, void *value) { 39 | NPError err = NPERR_NO_ERROR; 40 | switch (variable) { 41 | case NPPVpluginNameString: 42 | *reinterpret_cast(value) = 43 | "Embedded Emacs - Launcher"; 44 | break; 45 | case NPPVpluginDescriptionString: 46 | *reinterpret_cast(value) = 47 | "Private half of embedded emacs; takes a window id" 48 | " and launches your editor on behalf of the renderer."; 49 | break; 50 | default: 51 | err = Plugin::GetValue(variable, value); 52 | } 53 | return err; 54 | } 55 | 56 | npapi::PluginInstance* CreateInstance(NPMIMEType plugin_type, NPP npp, 57 | uint16_t mode, 58 | int16_t argc, 59 | char *argn[], char *argv[], 60 | NPSavedData* saved, 61 | NPError* error) { 62 | // TODO: Pass some of these arguments in?? 63 | return new EmacsManager(npp); 64 | } 65 | 66 | }; 67 | 68 | } // namespace 69 | 70 | namespace npapi { 71 | 72 | Plugin* Plugin::CreatePlugin() { 73 | return new EmacsPlugin(); 74 | } 75 | 76 | } // namespace npapi 77 | -------------------------------------------------------------------------------- /plugin/event_thread.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "event_thread.h" 6 | 7 | #include 8 | #include 9 | 10 | EventThread::EventThread() 11 | : thread_(NULL), 12 | main_context_(NULL), 13 | main_loop_(NULL) { 14 | main_context_ = g_main_context_new(); 15 | main_loop_ = g_main_loop_new(main_context_, FALSE); 16 | // TODO: error handling. 17 | thread_ = g_thread_create(EventThread::ThreadFunction, this, TRUE, NULL); 18 | } 19 | 20 | EventThread::~EventThread() { 21 | assert(g_thread_self() != thread_); 22 | // Stop the thread. 23 | g_main_loop_quit(main_loop_); 24 | g_thread_join(thread_); 25 | 26 | // Clean up. 27 | g_main_context_unref(main_context_); 28 | g_main_loop_unref(main_loop_); 29 | } 30 | 31 | void* EventThread::ThreadFunction(void* data) { 32 | EventThread* e = static_cast(data); 33 | g_main_loop_run(e->main_loop_); 34 | return NULL; 35 | } 36 | -------------------------------------------------------------------------------- /plugin/event_thread.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_EVENT_THREAD_H_ 6 | #define INCLUDED_EVENT_THREAD_H_ 7 | 8 | #include "util.h" 9 | 10 | G_FORWARD_DECLARE(GMainContext); 11 | G_FORWARD_DECLARE(GMainLoop); 12 | G_FORWARD_DECLARE(GThread); 13 | 14 | // A thread that runs a GMainLoop so we don't assume the browser has a 15 | // glib-based event loop. 16 | class EventThread { 17 | public: 18 | EventThread(); 19 | ~EventThread(); 20 | 21 | GMainContext* main_context() const { return main_context_; } 22 | 23 | private: 24 | GThread* thread_; 25 | GMainContext* main_context_; 26 | GMainLoop* main_loop_; 27 | 28 | static void* ThreadFunction(void* data); 29 | 30 | DISALLOW_COPY_AND_ASSIGN(EventThread); 31 | }; 32 | 33 | #endif // INCLUDED_EVENT_THREAD_H_ 34 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/browser.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2010 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "npapi-cxx/browser.h" 6 | 7 | #include 8 | #include 9 | 10 | #include "npapi-headers/npfunctions.h" 11 | 12 | namespace { 13 | 14 | NPNetscapeFuncs g_browser_functions = { 0 }; 15 | 16 | } // namespace 17 | 18 | namespace npapi { 19 | 20 | NPError InitializeBrowserFuncs(NPNetscapeFuncs* bFuncs) { 21 | if (!bFuncs) 22 | return NPERR_INVALID_FUNCTABLE_ERROR; 23 | 24 | int major_version = bFuncs->version >> 8; 25 | 26 | if (major_version != NP_VERSION_MAJOR) 27 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 28 | 29 | memcpy(&g_browser_functions, bFuncs, 30 | std::min(sizeof(g_browser_functions), (size_t)bFuncs->size)); 31 | 32 | return NPERR_NO_ERROR; 33 | } 34 | 35 | } // namespace npapi 36 | 37 | void NPN_Version(int* plugin_major, int* plugin_minor, 38 | int* netscape_major, int* netscape_minor) { 39 | if (netscape_major) 40 | *netscape_major = g_browser_functions.version >> 8; 41 | if (netscape_minor) 42 | *netscape_minor = g_browser_functions.version & 0xff; 43 | 44 | if (plugin_major) 45 | *plugin_major = NP_VERSION_MAJOR; 46 | if (plugin_minor) 47 | *plugin_minor = NP_VERSION_MINOR; 48 | } 49 | 50 | NPError NPN_GetValue(NPP instance, NPNVariable variable, void *value) { 51 | if (!g_browser_functions.getvalue) 52 | return NPERR_INVALID_FUNCTABLE_ERROR; 53 | return g_browser_functions.getvalue(instance, variable, value); 54 | } 55 | 56 | NPError NPN_SetValue(NPP instance, NPPVariable variable, void *value) { 57 | if (!g_browser_functions.setvalue) 58 | return NPERR_INVALID_FUNCTABLE_ERROR; 59 | return g_browser_functions.setvalue(instance, variable, value); 60 | } 61 | 62 | void* NPN_MemAlloc(uint32_t size) { 63 | if (!g_browser_functions.memalloc) 64 | return NULL; 65 | return g_browser_functions.memalloc(size); 66 | } 67 | 68 | NPObject *NPN_CreateObject(NPP npp, NPClass *aClass) { 69 | if (!g_browser_functions.createobject) 70 | return NULL; 71 | return g_browser_functions.createobject(npp, aClass); 72 | } 73 | 74 | NPObject *NPN_RetainObject(NPObject *npobj) { 75 | if (!g_browser_functions.retainobject) 76 | return NULL; 77 | return g_browser_functions.retainobject(npobj); 78 | } 79 | 80 | void NPN_ReleaseObject(NPObject *npobj) { 81 | if (!g_browser_functions.releaseobject) 82 | return; 83 | g_browser_functions.releaseobject(npobj); 84 | } 85 | 86 | NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name) { 87 | if (!g_browser_functions.getstringidentifier) 88 | return 0; 89 | return g_browser_functions.getstringidentifier(name); 90 | } 91 | 92 | void NPN_GetStringIdentifiers(const NPUTF8 **names, 93 | int32_t nameCount, 94 | NPIdentifier *identifiers) { 95 | if (!g_browser_functions.getstringidentifiers) 96 | return; 97 | g_browser_functions.getstringidentifiers(names, nameCount, identifiers); 98 | } 99 | 100 | bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, 101 | uint32_t argCount, NPVariant *result) { 102 | if (!g_browser_functions.invokeDefault) 103 | return false; 104 | return g_browser_functions.invokeDefault(npp, npobj, args, argCount, result); 105 | } 106 | 107 | void NPN_ReleaseVariantValue(NPVariant *variant) { 108 | if (!g_browser_functions.releasevariantvalue) 109 | return; 110 | g_browser_functions.releasevariantvalue(variant); 111 | } 112 | 113 | void NPN_SetException(NPObject *npobj, const NPUTF8 *message) { 114 | if (!g_browser_functions.setexception) 115 | return; 116 | g_browser_functions.setexception(npobj, message); 117 | } 118 | 119 | void NPN_PluginThreadAsyncCall(NPP plugin, 120 | void (*func)(void *), 121 | void *userData) { 122 | // FIXME: This will get called on another thread. Lock this guy? 123 | if (!g_browser_functions.pluginthreadasynccall) 124 | return; 125 | g_browser_functions.pluginthreadasynccall(plugin, func, userData); 126 | } 127 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/browser.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2010 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_BROWSER_H_ 6 | #define INCLUDED_BROWSER_H_ 7 | 8 | // Provide the NPN_* prototypes. 9 | #ifndef XP_UNIX 10 | #define XP_UNIX 1 11 | #endif 12 | #include "npapi-headers/npapi.h" 13 | 14 | typedef struct _NPNetscapeFuncs NPNetscapeFuncs; 15 | 16 | namespace npapi { 17 | 18 | NPError InitializeBrowserFuncs(NPNetscapeFuncs* bFuncs); 19 | 20 | } // namespace npapi 21 | 22 | #endif // INCLUDED_BROWSER_H_ 23 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/plugin.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | #include "browser.h" 11 | #include "npapi-headers/npfunctions.h" 12 | #include "plugin.h" 13 | #include "plugin_instance.h" 14 | 15 | /*****************************/ 16 | /* Plugin implementation */ 17 | /*****************************/ 18 | 19 | namespace { 20 | npapi::Plugin* g_plugin = NULL; 21 | } // namespace 22 | 23 | namespace npapi { 24 | 25 | Plugin::Plugin() { 26 | } 27 | 28 | Plugin::~Plugin() { 29 | } 30 | 31 | Plugin* Plugin::Get() { 32 | if (g_plugin == NULL) 33 | g_plugin = Plugin::CreatePlugin(); 34 | return g_plugin; 35 | } 36 | 37 | NPError Plugin::Init() { 38 | return NPERR_NO_ERROR; 39 | } 40 | 41 | NPError Plugin::GetValue(NPPVariable variable, void *value) { 42 | return NPERR_INVALID_PARAM; 43 | } 44 | 45 | } // namespace npapi 46 | 47 | /*****************************/ 48 | /* NP Functions */ 49 | /*****************************/ 50 | 51 | using npapi::Plugin; 52 | using npapi::PluginInstance; 53 | 54 | NPError NP_GetEntryPoints(NPPluginFuncs* pFuncs) { 55 | static NPPluginFuncs myFuncs; 56 | myFuncs.size = std::min((size_t)pFuncs->size, sizeof(myFuncs)); 57 | myFuncs.version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR; 58 | myFuncs.newp = NPP_New; 59 | myFuncs.destroy = NPP_Destroy; 60 | myFuncs.setwindow = NPP_SetWindow; 61 | myFuncs.getvalue = NPP_GetValue; 62 | memcpy(pFuncs, &myFuncs, myFuncs.size); 63 | return NPERR_NO_ERROR; 64 | } 65 | 66 | NPError NP_Initialize(NPNetscapeFuncs* bFuncs, 67 | NPPluginFuncs* pFuncs) { 68 | NPError err = npapi::InitializeBrowserFuncs(bFuncs); 69 | if (err != NPERR_NO_ERROR) 70 | return err; 71 | 72 | err = Plugin::Get()->Init(); 73 | if (err != NPERR_NO_ERROR) 74 | return err; 75 | 76 | // On Unix, it looks like NP_GetEntryPoints isn't called directly? 77 | // The prototype for NP_Initialize is different from everyone 78 | // else. Meh. 79 | return NP_GetEntryPoints(pFuncs); 80 | } 81 | 82 | NPError NP_GetValue(void *instance, 83 | NPPVariable variable, 84 | void *value) { 85 | return Plugin::Get()->GetValue(variable, value); 86 | } 87 | 88 | NPError NP_Shutdown(void) { 89 | delete g_plugin; 90 | return NPERR_NO_ERROR; 91 | } 92 | 93 | const char* NP_GetMIMEDescription(void) { 94 | return Plugin::Get()->GetMIMEDescription(); 95 | } 96 | 97 | /*****************************/ 98 | /* NPP Functions */ 99 | /*****************************/ 100 | 101 | #define GET_INSTANCE(npp, instance) \ 102 | if (!npp->pdata) \ 103 | return NPERR_INVALID_INSTANCE_ERROR; \ 104 | PluginInstance *instance = static_cast(npp->pdata) 105 | 106 | NPError NPP_New(NPMIMEType plugin_type, NPP npp, 107 | uint16_t mode, int16_t argc, char* argn[], 108 | char* argv[], NPSavedData* saved) { 109 | NPError err = NPERR_NO_ERROR; 110 | Plugin::Get()->CreateInstance(plugin_type, npp, mode, 111 | argc, argn, argv, saved, &err); 112 | return err; 113 | } 114 | 115 | NPError NPP_Destroy(NPP npp, NPSavedData** save) { 116 | GET_INSTANCE(npp, instance); 117 | delete instance; 118 | return NPERR_NO_ERROR; 119 | } 120 | 121 | NPError NPP_SetWindow(NPP npp, NPWindow* window) { 122 | GET_INSTANCE(npp, instance); 123 | return instance->SetWindow(window); 124 | } 125 | 126 | NPError NPP_GetValue(NPP npp, NPPVariable variable, void* value) { 127 | GET_INSTANCE(npp, instance); 128 | return instance->GetValue(variable, value); 129 | } 130 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/plugin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_PLUGIN_H_ 6 | #define INCLUDED_PLUGIN_H_ 7 | 8 | #include "npapi-headers/npapi.h" 9 | 10 | namespace npapi { 11 | 12 | class PluginInstance; 13 | 14 | class Plugin { 15 | public: 16 | // Constructors and destructors should be cheap. It seems that 17 | // Chrome will call NP_GetMIMEDescription before NP_Initialize 18 | // when probing, so it probably never even calls the latter. TODO: 19 | // Check if this is the case and if this means dtor needs to work 20 | // without init being called. 21 | Plugin(); 22 | virtual ~Plugin(); 23 | 24 | // This stub is for the plugin implementer to implement. 25 | static Plugin* CreatePlugin(); 26 | 27 | static Plugin* Get(); 28 | 29 | // Finish initializing the plugin; notably this bit can return an 30 | // error code. 31 | virtual NPError Init(); 32 | 33 | virtual NPError GetValue(NPPVariable variable, void *value); 34 | // NOTE: This function must be safe to call before init() is 35 | // called. 36 | virtual const char* GetMIMEDescription() = 0; 37 | 38 | virtual PluginInstance* CreateInstance(NPMIMEType plugin_type, NPP npp, 39 | uint16_t mode, 40 | int16_t argc, 41 | char *argn[], char *argv[], 42 | NPSavedData* saved, 43 | NPError* error) = 0; 44 | }; 45 | 46 | } // namespace npapi 47 | 48 | #endif // INCLUDED_PLUGIN_H_ 49 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/plugin_instance.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "plugin_instance.h" 6 | 7 | #include 8 | 9 | #include "task.h" 10 | 11 | namespace { 12 | 13 | void DeleteTaskThunk(void *ptr) { 14 | delete static_cast(ptr); 15 | } 16 | 17 | void ProcessTasksThunk(void *ptr) { 18 | static_cast(ptr)->ProcessTasks(); 19 | } 20 | 21 | } // namespace 22 | 23 | namespace npapi { 24 | 25 | PluginInstance::PluginInstance(NPP npp) 26 | : npp_(npp) { 27 | npp_->pdata = this; 28 | task_queue_ = g_async_queue_new_full(DeleteTaskThunk); 29 | } 30 | 31 | PluginInstance::~PluginInstance() { 32 | g_async_queue_unref(task_queue_); 33 | npp_->pdata = NULL; 34 | } 35 | 36 | void PluginInstance::PostTask(Task* task) { 37 | if (!task) return; 38 | g_async_queue_push(task_queue_, task); 39 | // No memory is allocated, so we don't care if this runs or 40 | // not. It may also run more often than necessary, but that's 41 | // okay. 42 | NPN_PluginThreadAsyncCall(npp_, ProcessTasksThunk, this); 43 | } 44 | 45 | void PluginInstance::ProcessTasks() { 46 | void* data; 47 | while ((data = g_async_queue_try_pop(task_queue_))) { 48 | Task* task = static_cast(data); 49 | task->Run(this); 50 | delete task; 51 | } 52 | } 53 | 54 | NPError PluginInstance::SetWindow(NPWindow* window) { 55 | return NPERR_NO_ERROR; 56 | } 57 | 58 | NPError PluginInstance::GetValue(NPPVariable variable, void* value) { 59 | return NPERR_INVALID_PARAM; 60 | } 61 | 62 | } // namespace npapi 63 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/plugin_instance.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_PLUGIN_INSTANCE_H_ 6 | #define INCLUDED_PLUGIN_INSTANCE_H_ 7 | 8 | #include "npapi-cxx/browser.h" 9 | #include "util.h" 10 | 11 | G_FORWARD_DECLARE(GAsyncQueue); 12 | 13 | namespace npapi { 14 | 15 | class Task; 16 | 17 | class PluginInstance { 18 | public: 19 | PluginInstance(NPP npp); 20 | virtual ~PluginInstance(); 21 | 22 | static PluginInstance* from_npp(NPP npp) { 23 | if (!npp) return NULL; 24 | return static_cast(npp->pdata); 25 | } 26 | 27 | NPP npp() { return npp_; } 28 | 29 | // Called on any thread. Safe to call until around the end of the 30 | // destructor. Caller is responsible for ensuring thread lifetime 31 | // is shorter than PluginInstance. 32 | void PostTask(Task* task); 33 | // Called on the main plugin thread. 34 | void ProcessTasks(); 35 | 36 | virtual NPError SetWindow(NPWindow* window); 37 | virtual NPError GetValue(NPPVariable variable, void* value); 38 | private: 39 | NPP npp_; 40 | 41 | GAsyncQueue* task_queue_; 42 | 43 | DISALLOW_COPY_AND_ASSIGN(PluginInstance); 44 | }; 45 | 46 | } // namespace npapi 47 | 48 | #endif // INCLUDED_PLUGIN_INSTANCE_H_ 49 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/scoped_npobject.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2010 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_SCOPED_NPOBJECT_H_ 6 | #define INCLUDED_SCOPED_NPOBJECT_H_ 7 | 8 | #include "npapi-headers/npruntime.h" 9 | #include "util.h" 10 | 11 | namespace npapi { 12 | 13 | template 14 | class scoped_npobject { 15 | public: 16 | explicit scoped_npobject(T* obj = NULL) : obj_(obj) { 17 | reset(obj); 18 | } 19 | ~scoped_npobject() { 20 | reset(); 21 | } 22 | T* get() { 23 | return obj_; 24 | } 25 | void reset(T* obj = NULL) { 26 | if (obj) 27 | NPN_RetainObject(obj); 28 | if (obj_) 29 | NPN_ReleaseObject(obj_); 30 | obj_ = obj; 31 | } 32 | T* release() { 33 | T* obj = obj_; 34 | obj_ = NULL; 35 | return obj; 36 | } 37 | private: 38 | T* obj_; 39 | DISALLOW_COPY_AND_ASSIGN(scoped_npobject); 40 | }; 41 | 42 | } // namespace npapi 43 | 44 | #endif // INCLUDED_SCOPED_NPOBJECT_H_ 45 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/script_object.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "npapi-cxx/script_object.h" 6 | 7 | #include "npapi-cxx/plugin_instance.h" 8 | 9 | namespace npapi { 10 | 11 | ScriptObjectBase::ScriptObjectBase(NPP npp) 12 | : npp_(npp) { 13 | } 14 | 15 | ScriptObjectBase::~ScriptObjectBase() { 16 | } 17 | 18 | PluginInstance* ScriptObjectBase::plugin_instance() { 19 | return PluginInstance::from_npp(npp_); 20 | } 21 | 22 | void ScriptObjectBase::Invalidate() { 23 | npp_ = NULL; 24 | } 25 | 26 | bool ScriptObjectBase::HasMethod(NPIdentifier name) { 27 | return false; 28 | } 29 | 30 | bool ScriptObjectBase::Invoke(NPIdentifier name, 31 | const NPVariant *args, 32 | uint32_t arg_count, 33 | NPVariant *result) { 34 | return false; 35 | } 36 | 37 | bool ScriptObjectBase::InvokeDefault(const NPVariant *args, 38 | uint32_t arg_count, 39 | NPVariant *result) { 40 | return false; 41 | } 42 | 43 | bool ScriptObjectBase::HasProperty(NPIdentifier name) { 44 | return false; 45 | } 46 | 47 | bool ScriptObjectBase::GetProperty(NPIdentifier name, NPVariant *result) { 48 | return false; 49 | } 50 | 51 | bool ScriptObjectBase::SetProperty(NPIdentifier name, const NPVariant *value) { 52 | return false; 53 | } 54 | 55 | bool ScriptObjectBase::RemoveProperty(NPIdentifier name) { 56 | return false; 57 | } 58 | 59 | bool ScriptObjectBase::Enumerate(NPIdentifier **identifiers, 60 | uint32_t *identifier_count) { 61 | return false; 62 | } 63 | 64 | bool ScriptObjectBase::Construct(const NPVariant *args, uint32_t arg_count, 65 | NPVariant *result) { 66 | return false; 67 | } 68 | 69 | // static 70 | void ScriptObjectBase::DeallocateThunk(NPObject *npobj) { 71 | delete static_cast(npobj); 72 | } 73 | 74 | // static 75 | void ScriptObjectBase::InvalidateThunk(NPObject *npobj) { 76 | static_cast(npobj)->Invalidate(); 77 | } 78 | 79 | // static 80 | bool ScriptObjectBase::HasMethodThunk(NPObject *npobj, NPIdentifier name) { 81 | return static_cast(npobj)->HasMethod(name); 82 | } 83 | 84 | // static 85 | bool ScriptObjectBase::InvokeThunk( 86 | NPObject *npobj, NPIdentifier name, 87 | const NPVariant *args, uint32_t arg_count, NPVariant *result) { 88 | return static_cast(npobj)->Invoke(name, args, arg_count, 89 | result); 90 | } 91 | 92 | // static 93 | bool ScriptObjectBase::InvokeDefaultThunk( 94 | NPObject *npobj, const NPVariant *args, uint32_t arg_count, 95 | NPVariant *result) { 96 | return static_cast(npobj)->InvokeDefault( 97 | args, arg_count, result); 98 | } 99 | 100 | // static 101 | bool ScriptObjectBase::HasPropertyThunk(NPObject *npobj, NPIdentifier name) { 102 | return static_cast(npobj)->HasProperty(name); 103 | } 104 | 105 | // static 106 | bool ScriptObjectBase::GetPropertyThunk(NPObject *npobj, 107 | NPIdentifier name, 108 | NPVariant *result) { 109 | return static_cast(npobj)->GetProperty(name, result); 110 | } 111 | 112 | // static 113 | bool ScriptObjectBase::SetPropertyThunk(NPObject *npobj, 114 | NPIdentifier name, 115 | const NPVariant *value) { 116 | return static_cast(npobj)->SetProperty(name, value); 117 | } 118 | 119 | // static 120 | bool ScriptObjectBase::RemovePropertyThunk(NPObject *npobj, NPIdentifier name) { 121 | return static_cast(npobj)->RemoveProperty(name); 122 | } 123 | 124 | // static 125 | bool ScriptObjectBase::EnumerateThunk(NPObject *npobj, 126 | NPIdentifier **identifiers, 127 | uint32_t *identifier_count) { 128 | return static_cast(npobj)->Enumerate(identifiers, 129 | identifier_count); 130 | } 131 | 132 | // static 133 | bool ScriptObjectBase::ConstructThunk(NPObject *npobj, 134 | const NPVariant *args, uint32_t arg_count, 135 | NPVariant *result) { 136 | return static_cast(npobj)->Construct(args, arg_count, result); 137 | } 138 | 139 | } // namespace npapi 140 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/script_object.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_SCRIPT_OBJECT_H_ 6 | #define INCLUDED_SCRIPT_OBJECT_H_ 7 | 8 | #include "npapi-cxx/browser.h" 9 | #include "npapi-headers/npruntime.h" 10 | #include "util.h" 11 | 12 | namespace npapi { 13 | 14 | class PluginInstance; 15 | 16 | class ScriptObjectBase : public NPObject { 17 | public: 18 | virtual void Invalidate(); 19 | virtual bool HasMethod(NPIdentifier name); 20 | virtual bool Invoke(NPIdentifier name, 21 | const NPVariant *args, 22 | uint32_t arg_count, 23 | NPVariant *result); 24 | virtual bool InvokeDefault(const NPVariant *args, uint32_t arg_count, 25 | NPVariant *result); 26 | virtual bool HasProperty(NPIdentifier name); 27 | virtual bool GetProperty(NPIdentifier name, NPVariant *result); 28 | virtual bool SetProperty(NPIdentifier name, const NPVariant *value); 29 | virtual bool RemoveProperty(NPIdentifier name); 30 | virtual bool Enumerate(NPIdentifier **identifiers, 31 | uint32_t *identifier_count); 32 | virtual bool Construct(const NPVariant *args, uint32_t arg_count, 33 | NPVariant *result); 34 | 35 | PluginInstance* plugin_instance(); 36 | 37 | protected: 38 | static void DeallocateThunk(NPObject *npobj); 39 | static void InvalidateThunk(NPObject *npobj); 40 | static bool HasMethodThunk(NPObject *npobj, NPIdentifier name); 41 | static bool InvokeThunk(NPObject *npobj, NPIdentifier name, 42 | const NPVariant *args, uint32_t arg_count, 43 | NPVariant *result); 44 | static bool InvokeDefaultThunk(NPObject *npobj, 45 | const NPVariant *args, uint32_t arg_count, 46 | NPVariant *result); 47 | static bool HasPropertyThunk(NPObject *npobj, NPIdentifier name); 48 | static bool GetPropertyThunk(NPObject *npobj, 49 | NPIdentifier name, 50 | NPVariant *result); 51 | static bool SetPropertyThunk(NPObject *npobj, 52 | NPIdentifier name, 53 | const NPVariant *value); 54 | static bool RemovePropertyThunk(NPObject *npobj, NPIdentifier name); 55 | static bool EnumerateThunk(NPObject *npobj, NPIdentifier **identifiers, 56 | uint32_t *identifier_count); 57 | static bool ConstructThunk(NPObject *npobj, 58 | const NPVariant *args, 59 | uint32_t arg_count, 60 | NPVariant *result); 61 | ScriptObjectBase(NPP npp); 62 | ~ScriptObjectBase(); 63 | 64 | NPP npp_; 65 | 66 | private: 67 | DISALLOW_COPY_AND_ASSIGN(ScriptObjectBase); 68 | }; 69 | 70 | template 71 | class ScriptObject : public ScriptObjectBase { 72 | public: 73 | static T* Create(NPP npp) { 74 | return static_cast(NPN_CreateObject(npp, &npclass)); 75 | } 76 | 77 | protected: 78 | static NPClass npclass; 79 | 80 | static NPObject* AllocateThunk(NPP npp, NPClass *aClass) { 81 | return new T(npp); 82 | } 83 | 84 | ScriptObject(NPP npp) : ScriptObjectBase(npp) {} 85 | 86 | private: 87 | DISALLOW_COPY_AND_ASSIGN(ScriptObject); 88 | }; 89 | 90 | // Apparently I'm not allowed to define this inline. Okay, then. 91 | template 92 | NPClass ScriptObject::npclass = { 93 | NP_CLASS_STRUCT_VERSION, 94 | ScriptObject::AllocateThunk, // allocate 95 | ScriptObjectBase::DeallocateThunk, // deallocate 96 | ScriptObjectBase::InvalidateThunk, // invalidate 97 | ScriptObjectBase::HasMethodThunk, // hasMethod 98 | ScriptObjectBase::InvokeThunk, // invoke 99 | ScriptObjectBase::InvokeDefaultThunk, // invokeDefault 100 | ScriptObjectBase::HasPropertyThunk, // hasProperty 101 | ScriptObjectBase::GetPropertyThunk, // getProperty 102 | ScriptObjectBase::SetPropertyThunk, // setProperty 103 | ScriptObjectBase::RemovePropertyThunk, // removeProperty 104 | ScriptObjectBase::EnumerateThunk, // enumerate 105 | ScriptObjectBase::ConstructThunk, // construct 106 | }; 107 | 108 | } // namespace npapi 109 | 110 | 111 | #endif // INCLUDED_SCRIPT_OBJECT_H_ 112 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/task.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2010 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "npapi-cxx/task.h" 6 | 7 | namespace npapi { 8 | 9 | Task::~Task() 10 | { 11 | } 12 | 13 | } // namespace npapi 14 | -------------------------------------------------------------------------------- /plugin/npapi-cxx/task.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_TASK_H_ 6 | #define INCLUDED_TASK_H_ 7 | 8 | namespace npapi { 9 | 10 | class PluginInstance; 11 | 12 | class Task { 13 | public: 14 | // Don't inline this to avoid emitting everywhere. 15 | virtual ~Task(); 16 | virtual void Run(PluginInstance* instance) = 0; 17 | }; 18 | 19 | } // namespace npapi 20 | 21 | #endif // INCLUDED_TASK_H_ 22 | -------------------------------------------------------------------------------- /plugin/npapi-headers/npapi.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * either the GNU General Public License Version 2 or later (the "GPL"), or 26 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 27 | * in which case the provisions of the GPL or the LGPL are applicable instead 28 | * of those above. If you wish to allow use of your version of this file only 29 | * under the terms of either the GPL or the LGPL, and not to allow others to 30 | * use your version of this file under the terms of the MPL, indicate your 31 | * decision by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL or the LGPL. If you do not delete 33 | * the provisions above, a recipient may use your version of this file under 34 | * the terms of any one of the MPL, the GPL or the LGPL. 35 | * 36 | * ***** END LICENSE BLOCK ***** */ 37 | 38 | #ifndef npapi_h_ 39 | #define npapi_h_ 40 | 41 | #if defined(__OS2__) 42 | #pragma pack(1) 43 | #endif 44 | 45 | #include "nptypes.h" 46 | 47 | #if defined(__OS2__) || defined(OS2) 48 | #ifndef XP_OS2 49 | #define XP_OS2 1 50 | #endif 51 | #endif 52 | 53 | #if defined(_WIN32) && !defined(__SYMBIAN32__) 54 | #include 55 | #ifndef XP_WIN 56 | #define XP_WIN 1 57 | #endif 58 | #endif 59 | 60 | #if defined(__SYMBIAN32__) 61 | #ifndef XP_SYMBIAN 62 | #define XP_SYMBIAN 1 63 | #undef XP_WIN 64 | #endif 65 | #endif 66 | 67 | #if defined(__APPLE_CC__) && !defined(XP_UNIX) 68 | #ifndef XP_MACOSX 69 | #define XP_MACOSX 1 70 | #endif 71 | #endif 72 | 73 | #if defined(XP_MACOSX) && defined(__LP64__) 74 | #define NP_NO_QUICKDRAW 75 | #define NP_NO_CARBON 76 | #endif 77 | 78 | #if defined(XP_MACOSX) 79 | #include 80 | #include 81 | #ifndef NP_NO_CARBON 82 | #include 83 | #endif 84 | #endif 85 | 86 | #if defined(XP_UNIX) 87 | #include 88 | #if defined(MOZ_X11) 89 | #include 90 | #include 91 | #endif 92 | #endif 93 | 94 | #if defined(XP_SYMBIAN) 95 | #include 96 | #include 97 | #endif 98 | 99 | /*----------------------------------------------------------------------*/ 100 | /* Plugin Version Constants */ 101 | /*----------------------------------------------------------------------*/ 102 | 103 | #define NP_VERSION_MAJOR 0 104 | #define NP_VERSION_MINOR 27 105 | 106 | 107 | /* The OS/2 version of Netscape uses RC_DATA to define the 108 | mime types, file extensions, etc that are required. 109 | Use a vertical bar to separate types, end types with \0. 110 | FileVersion and ProductVersion are 32bit ints, all other 111 | entries are strings that MUST be terminated with a \0. 112 | 113 | AN EXAMPLE: 114 | 115 | RCDATA NP_INFO_ProductVersion { 1,0,0,1,} 116 | 117 | RCDATA NP_INFO_MIMEType { "video/x-video|", 118 | "video/x-flick\0" } 119 | RCDATA NP_INFO_FileExtents { "avi|", 120 | "flc\0" } 121 | RCDATA NP_INFO_FileOpenName{ "MMOS2 video player(*.avi)|", 122 | "MMOS2 Flc/Fli player(*.flc)\0" } 123 | 124 | RCDATA NP_INFO_FileVersion { 1,0,0,1 } 125 | RCDATA NP_INFO_CompanyName { "Netscape Communications\0" } 126 | RCDATA NP_INFO_FileDescription { "NPAVI32 Extension DLL\0" 127 | RCDATA NP_INFO_InternalName { "NPAVI32\0" ) 128 | RCDATA NP_INFO_LegalCopyright { "Copyright Netscape Communications \251 1996\0" 129 | RCDATA NP_INFO_OriginalFilename { "NVAPI32.DLL" } 130 | RCDATA NP_INFO_ProductName { "NPAVI32 Dynamic Link Library\0" } 131 | */ 132 | /* RC_DATA types for version info - required */ 133 | #define NP_INFO_ProductVersion 1 134 | #define NP_INFO_MIMEType 2 135 | #define NP_INFO_FileOpenName 3 136 | #define NP_INFO_FileExtents 4 137 | /* RC_DATA types for version info - used if found */ 138 | #define NP_INFO_FileDescription 5 139 | #define NP_INFO_ProductName 6 140 | /* RC_DATA types for version info - optional */ 141 | #define NP_INFO_CompanyName 7 142 | #define NP_INFO_FileVersion 8 143 | #define NP_INFO_InternalName 9 144 | #define NP_INFO_LegalCopyright 10 145 | #define NP_INFO_OriginalFilename 11 146 | 147 | #ifndef RC_INVOKED 148 | 149 | /*----------------------------------------------------------------------*/ 150 | /* Definition of Basic Types */ 151 | /*----------------------------------------------------------------------*/ 152 | 153 | typedef unsigned char NPBool; 154 | typedef int16_t NPError; 155 | typedef int16_t NPReason; 156 | typedef char* NPMIMEType; 157 | 158 | /*----------------------------------------------------------------------*/ 159 | /* Structures and definitions */ 160 | /*----------------------------------------------------------------------*/ 161 | 162 | #if !defined(__LP64__) 163 | #if defined(XP_MACOSX) 164 | #pragma options align=mac68k 165 | #endif 166 | #endif /* __LP64__ */ 167 | 168 | /* 169 | * NPP is a plug-in's opaque instance handle 170 | */ 171 | typedef struct _NPP 172 | { 173 | void* pdata; /* plug-in private data */ 174 | void* ndata; /* netscape private data */ 175 | } NPP_t; 176 | 177 | typedef NPP_t* NPP; 178 | 179 | typedef struct _NPStream 180 | { 181 | void* pdata; /* plug-in private data */ 182 | void* ndata; /* netscape private data */ 183 | const char* url; 184 | uint32_t end; 185 | uint32_t lastmodified; 186 | void* notifyData; 187 | const char* headers; /* Response headers from host. 188 | * Exists only for >= NPVERS_HAS_RESPONSE_HEADERS. 189 | * Used for HTTP only; NULL for non-HTTP. 190 | * Available from NPP_NewStream onwards. 191 | * Plugin should copy this data before storing it. 192 | * Includes HTTP status line and all headers, 193 | * preferably verbatim as received from server, 194 | * headers formatted as in HTTP ("Header: Value"), 195 | * and newlines (\n, NOT \r\n) separating lines. 196 | * Terminated by \n\0 (NOT \n\n\0). */ 197 | } NPStream; 198 | 199 | typedef struct _NPByteRange 200 | { 201 | int32_t offset; /* negative offset means from the end */ 202 | uint32_t length; 203 | struct _NPByteRange* next; 204 | } NPByteRange; 205 | 206 | typedef struct _NPSavedData 207 | { 208 | int32_t len; 209 | void* buf; 210 | } NPSavedData; 211 | 212 | typedef struct _NPRect 213 | { 214 | uint16_t top; 215 | uint16_t left; 216 | uint16_t bottom; 217 | uint16_t right; 218 | } NPRect; 219 | 220 | typedef struct _NPSize 221 | { 222 | int32_t width; 223 | int32_t height; 224 | } NPSize; 225 | 226 | typedef enum { 227 | NPFocusNext = 0, 228 | NPFocusPrevious = 1 229 | } NPFocusDirection; 230 | 231 | /* Return values for NPP_HandleEvent */ 232 | #define kNPEventNotHandled 0 233 | #define kNPEventHandled 1 234 | /* Exact meaning must be spec'd in event model. */ 235 | #define kNPEventStartIME 2 236 | 237 | #if defined(XP_UNIX) 238 | /* 239 | * Unix specific structures and definitions 240 | */ 241 | 242 | /* 243 | * Callback Structures. 244 | * 245 | * These are used to pass additional platform specific information. 246 | */ 247 | enum { 248 | NP_SETWINDOW = 1, 249 | NP_PRINT 250 | }; 251 | 252 | typedef struct 253 | { 254 | int32_t type; 255 | } NPAnyCallbackStruct; 256 | 257 | typedef struct 258 | { 259 | int32_t type; 260 | #if defined(MOZ_X11) 261 | Display* display; 262 | Visual* visual; 263 | Colormap colormap; 264 | unsigned int depth; 265 | #endif 266 | } NPSetWindowCallbackStruct; 267 | 268 | typedef struct 269 | { 270 | int32_t type; 271 | FILE* fp; 272 | } NPPrintCallbackStruct; 273 | 274 | #endif /* XP_UNIX */ 275 | 276 | #if defined(XP_MACOSX) 277 | typedef enum { 278 | #ifndef NP_NO_QUICKDRAW 279 | NPDrawingModelQuickDraw = 0, 280 | #endif 281 | NPDrawingModelCoreGraphics = 1, 282 | NPDrawingModelOpenGL = 2, 283 | NPDrawingModelCoreAnimation = 3, 284 | NPDrawingModelInvalidatingCoreAnimation = 4 285 | } NPDrawingModel; 286 | 287 | typedef enum { 288 | #ifndef NP_NO_CARBON 289 | NPEventModelCarbon = 0, 290 | #endif 291 | NPEventModelCocoa = 1 292 | } NPEventModel; 293 | #endif 294 | 295 | /* 296 | * The following masks are applied on certain platforms to NPNV and 297 | * NPPV selectors that pass around pointers to COM interfaces. Newer 298 | * compilers on some platforms may generate vtables that are not 299 | * compatible with older compilers. To prevent older plugins from 300 | * not understanding a new browser's ABI, these masks change the 301 | * values of those selectors on those platforms. To remain backwards 302 | * compatible with different versions of the browser, plugins can 303 | * use these masks to dynamically determine and use the correct C++ 304 | * ABI that the browser is expecting. This does not apply to Windows 305 | * as Microsoft's COM ABI will likely not change. 306 | */ 307 | 308 | #define NP_ABI_GCC3_MASK 0x10000000 309 | /* 310 | * gcc 3.x generated vtables on UNIX and OSX are incompatible with 311 | * previous compilers. 312 | */ 313 | #if (defined(XP_UNIX) && defined(__GNUC__) && (__GNUC__ >= 3)) 314 | #define _NP_ABI_MIXIN_FOR_GCC3 NP_ABI_GCC3_MASK 315 | #else 316 | #define _NP_ABI_MIXIN_FOR_GCC3 0 317 | #endif 318 | 319 | #if defined(XP_MACOSX) 320 | #define NP_ABI_MACHO_MASK 0x01000000 321 | #define _NP_ABI_MIXIN_FOR_MACHO NP_ABI_MACHO_MASK 322 | #else 323 | #define _NP_ABI_MIXIN_FOR_MACHO 0 324 | #endif 325 | 326 | #define NP_ABI_MASK (_NP_ABI_MIXIN_FOR_GCC3 | _NP_ABI_MIXIN_FOR_MACHO) 327 | 328 | /* 329 | * List of variable names for which NPP_GetValue shall be implemented 330 | */ 331 | typedef enum { 332 | NPPVpluginNameString = 1, 333 | NPPVpluginDescriptionString, 334 | NPPVpluginWindowBool, 335 | NPPVpluginTransparentBool, 336 | NPPVjavaClass, 337 | NPPVpluginWindowSize, 338 | NPPVpluginTimerInterval, 339 | NPPVpluginScriptableInstance = (10 | NP_ABI_MASK), 340 | NPPVpluginScriptableIID = 11, 341 | NPPVjavascriptPushCallerBool = 12, 342 | NPPVpluginKeepLibraryInMemory = 13, 343 | NPPVpluginNeedsXEmbed = 14, 344 | 345 | /* Get the NPObject for scripting the plugin. Introduced in NPAPI minor version 14. 346 | */ 347 | NPPVpluginScriptableNPObject = 15, 348 | 349 | /* Get the plugin value (as \0-terminated UTF-8 string data) for 350 | * form submission if the plugin is part of a form. Use 351 | * NPN_MemAlloc() to allocate memory for the string data. Introduced 352 | * in NPAPI minor version 15. 353 | */ 354 | NPPVformValue = 16, 355 | 356 | NPPVpluginUrlRequestsDisplayedBool = 17, 357 | 358 | /* Checks if the plugin is interested in receiving the http body of 359 | * all http requests (including failed ones, http status != 200). 360 | */ 361 | NPPVpluginWantsAllNetworkStreams = 18, 362 | 363 | /* Browsers can retrieve a native ATK accessibility plug ID via this variable. */ 364 | NPPVpluginNativeAccessibleAtkPlugId = 19, 365 | 366 | /* Checks to see if the plug-in would like the browser to load the "src" attribute. */ 367 | NPPVpluginCancelSrcStream = 20, 368 | 369 | NPPVsupportsAdvancedKeyHandling = 21, 370 | 371 | NPPVpluginUsesDOMForCursorBool = 22 372 | 373 | #if defined(XP_MACOSX) 374 | /* Used for negotiating drawing models */ 375 | , NPPVpluginDrawingModel = 1000 376 | /* Used for negotiating event models */ 377 | , NPPVpluginEventModel = 1001 378 | /* In the NPDrawingModelCoreAnimation drawing model, the browser asks the plug-in for a Core Animation layer. */ 379 | , NPPVpluginCoreAnimationLayer = 1003 380 | #endif 381 | 382 | #if defined(MOZ_PLATFORM_MAEMO) && ((MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)) 383 | , NPPVpluginWindowlessLocalBool = 2002 384 | #endif 385 | } NPPVariable; 386 | 387 | /* 388 | * List of variable names for which NPN_GetValue should be implemented. 389 | */ 390 | typedef enum { 391 | NPNVxDisplay = 1, 392 | NPNVxtAppContext, 393 | NPNVnetscapeWindow, 394 | NPNVjavascriptEnabledBool, 395 | NPNVasdEnabledBool, 396 | NPNVisOfflineBool, 397 | 398 | NPNVserviceManager = (10 | NP_ABI_MASK), 399 | NPNVDOMElement = (11 | NP_ABI_MASK), 400 | NPNVDOMWindow = (12 | NP_ABI_MASK), 401 | NPNVToolkit = (13 | NP_ABI_MASK), 402 | NPNVSupportsXEmbedBool = 14, 403 | 404 | /* Get the NPObject wrapper for the browser window. */ 405 | NPNVWindowNPObject = 15, 406 | 407 | /* Get the NPObject wrapper for the plugins DOM element. */ 408 | NPNVPluginElementNPObject = 16, 409 | 410 | NPNVSupportsWindowless = 17, 411 | 412 | NPNVprivateModeBool = 18, 413 | 414 | NPNVsupportsAdvancedKeyHandling = 21, 415 | 416 | NPNVdocumentOrigin = 22 417 | 418 | #if defined(XP_MACOSX) 419 | /* Used for negotiating drawing models */ 420 | , NPNVpluginDrawingModel = 1000 421 | #ifndef NP_NO_QUICKDRAW 422 | , NPNVsupportsQuickDrawBool = 2000 423 | #endif 424 | , NPNVsupportsCoreGraphicsBool = 2001 425 | , NPNVsupportsOpenGLBool = 2002 426 | , NPNVsupportsCoreAnimationBool = 2003 427 | , NPNVsupportsInvalidatingCoreAnimationBool = 2004 428 | #ifndef NP_NO_CARBON 429 | , NPNVsupportsCarbonBool = 3000 /* TRUE if the browser supports the Carbon event model */ 430 | #endif 431 | , NPNVsupportsCocoaBool = 3001 /* TRUE if the browser supports the Cocoa event model */ 432 | , NPNVsupportsUpdatedCocoaTextInputBool = 3002 /* TRUE if the browser supports the updated 433 | Cocoa text input specification. */ 434 | , NPNVsupportsCompositingCoreAnimationPluginsBool = 74656 /* TRUE if the browser supports 435 | CA model compositing */ 436 | #endif 437 | #if defined(MOZ_PLATFORM_MAEMO) && ((MOZ_PLATFORM_MAEMO == 5) || (MOZ_PLATFORM_MAEMO == 6)) 438 | , NPNVSupportsWindowlessLocal = 2002 439 | #endif 440 | } NPNVariable; 441 | 442 | typedef enum { 443 | NPNURLVCookie = 501, 444 | NPNURLVProxy 445 | } NPNURLVariable; 446 | 447 | /* 448 | * The type of Toolkit the widgets use 449 | */ 450 | typedef enum { 451 | NPNVGtk12 = 1, 452 | NPNVGtk2 453 | } NPNToolkitType; 454 | 455 | /* 456 | * The type of a NPWindow - it specifies the type of the data structure 457 | * returned in the window field. 458 | */ 459 | typedef enum { 460 | NPWindowTypeWindow = 1, 461 | NPWindowTypeDrawable 462 | } NPWindowType; 463 | 464 | typedef struct _NPWindow 465 | { 466 | void* window; /* Platform specific window handle */ 467 | /* OS/2: x - Position of bottom left corner */ 468 | /* OS/2: y - relative to visible netscape window */ 469 | int32_t x; /* Position of top left corner relative */ 470 | int32_t y; /* to a netscape page. */ 471 | uint32_t width; /* Maximum window size */ 472 | uint32_t height; 473 | NPRect clipRect; /* Clipping rectangle in port coordinates */ 474 | #if (defined(XP_UNIX) || defined(XP_SYMBIAN)) && !defined(XP_MACOSX) 475 | void * ws_info; /* Platform-dependent additional data */ 476 | #endif /* XP_UNIX */ 477 | NPWindowType type; /* Is this a window or a drawable? */ 478 | } NPWindow; 479 | 480 | typedef struct _NPImageExpose 481 | { 482 | char* data; /* image pointer */ 483 | int32_t stride; /* Stride of data image pointer */ 484 | int32_t depth; /* Depth of image pointer */ 485 | int32_t x; /* Expose x */ 486 | int32_t y; /* Expose y */ 487 | uint32_t width; /* Expose width */ 488 | uint32_t height; /* Expose height */ 489 | NPSize dataSize; /* Data buffer size */ 490 | float translateX; /* translate X matrix value */ 491 | float translateY; /* translate Y matrix value */ 492 | float scaleX; /* scale X matrix value */ 493 | float scaleY; /* scale Y matrix value */ 494 | } NPImageExpose; 495 | 496 | typedef struct _NPFullPrint 497 | { 498 | NPBool pluginPrinted;/* Set TRUE if plugin handled fullscreen printing */ 499 | NPBool printOne; /* TRUE if plugin should print one copy to default 500 | printer */ 501 | void* platformPrint; /* Platform-specific printing info */ 502 | } NPFullPrint; 503 | 504 | typedef struct _NPEmbedPrint 505 | { 506 | NPWindow window; 507 | void* platformPrint; /* Platform-specific printing info */ 508 | } NPEmbedPrint; 509 | 510 | typedef struct _NPPrint 511 | { 512 | uint16_t mode; /* NP_FULL or NP_EMBED */ 513 | union 514 | { 515 | NPFullPrint fullPrint; /* if mode is NP_FULL */ 516 | NPEmbedPrint embedPrint; /* if mode is NP_EMBED */ 517 | } print; 518 | } NPPrint; 519 | 520 | #if defined(XP_MACOSX) 521 | #ifndef NP_NO_CARBON 522 | typedef EventRecord NPEvent; 523 | #endif 524 | #elif defined(XP_SYMBIAN) 525 | typedef QEvent NPEvent; 526 | #elif defined(XP_WIN) 527 | typedef struct _NPEvent 528 | { 529 | uint16_t event; 530 | uintptr_t wParam; 531 | uintptr_t lParam; 532 | } NPEvent; 533 | #elif defined(XP_OS2) 534 | typedef struct _NPEvent 535 | { 536 | uint32_t event; 537 | uint32_t wParam; 538 | uint32_t lParam; 539 | } NPEvent; 540 | #elif defined(XP_UNIX) && defined(MOZ_X11) 541 | typedef XEvent NPEvent; 542 | #else 543 | typedef void* NPEvent; 544 | #endif 545 | 546 | #if defined(XP_MACOSX) 547 | typedef void* NPRegion; 548 | #ifndef NP_NO_QUICKDRAW 549 | typedef RgnHandle NPQDRegion; 550 | #endif 551 | typedef CGPathRef NPCGRegion; 552 | #elif defined(XP_WIN) 553 | typedef HRGN NPRegion; 554 | #elif defined(XP_UNIX) && defined(MOZ_X11) 555 | typedef Region NPRegion; 556 | #elif defined(XP_SYMBIAN) 557 | typedef QRegion* NPRegion; 558 | #else 559 | typedef void *NPRegion; 560 | #endif 561 | 562 | typedef struct _NPNSString NPNSString; 563 | typedef struct _NPNSWindow NPNSWindow; 564 | typedef struct _NPNSMenu NPNSMenu; 565 | 566 | #if defined(XP_MACOSX) 567 | typedef NPNSMenu NPMenu; 568 | #else 569 | typedef void *NPMenu; 570 | #endif 571 | 572 | typedef enum { 573 | NPCoordinateSpacePlugin = 1, 574 | NPCoordinateSpaceWindow, 575 | NPCoordinateSpaceFlippedWindow, 576 | NPCoordinateSpaceScreen, 577 | NPCoordinateSpaceFlippedScreen 578 | } NPCoordinateSpace; 579 | 580 | #if defined(XP_MACOSX) 581 | 582 | #ifndef NP_NO_QUICKDRAW 583 | typedef struct NP_Port 584 | { 585 | CGrafPtr port; 586 | int32_t portx; /* position inside the topmost window */ 587 | int32_t porty; 588 | } NP_Port; 589 | #endif /* NP_NO_QUICKDRAW */ 590 | 591 | /* 592 | * NP_CGContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelCoreGraphics 593 | * as its drawing model. 594 | */ 595 | 596 | typedef struct NP_CGContext 597 | { 598 | CGContextRef context; 599 | void *window; /* A WindowRef under the Carbon event model. */ 600 | } NP_CGContext; 601 | 602 | /* 603 | * NP_GLContext is the type of the NPWindow's 'window' when the plugin specifies NPDrawingModelOpenGL as its 604 | * drawing model. 605 | */ 606 | 607 | typedef struct NP_GLContext 608 | { 609 | CGLContextObj context; 610 | #ifdef NP_NO_CARBON 611 | NPNSWindow *window; 612 | #else 613 | void *window; /* Can be either an NSWindow or a WindowRef depending on the event model */ 614 | #endif 615 | } NP_GLContext; 616 | 617 | typedef enum { 618 | NPCocoaEventDrawRect = 1, 619 | NPCocoaEventMouseDown, 620 | NPCocoaEventMouseUp, 621 | NPCocoaEventMouseMoved, 622 | NPCocoaEventMouseEntered, 623 | NPCocoaEventMouseExited, 624 | NPCocoaEventMouseDragged, 625 | NPCocoaEventKeyDown, 626 | NPCocoaEventKeyUp, 627 | NPCocoaEventFlagsChanged, 628 | NPCocoaEventFocusChanged, 629 | NPCocoaEventWindowFocusChanged, 630 | NPCocoaEventScrollWheel, 631 | NPCocoaEventTextInput 632 | } NPCocoaEventType; 633 | 634 | typedef struct _NPCocoaEvent { 635 | NPCocoaEventType type; 636 | uint32_t version; 637 | union { 638 | struct { 639 | uint32_t modifierFlags; 640 | double pluginX; 641 | double pluginY; 642 | int32_t buttonNumber; 643 | int32_t clickCount; 644 | double deltaX; 645 | double deltaY; 646 | double deltaZ; 647 | } mouse; 648 | struct { 649 | uint32_t modifierFlags; 650 | NPNSString *characters; 651 | NPNSString *charactersIgnoringModifiers; 652 | NPBool isARepeat; 653 | uint16_t keyCode; 654 | } key; 655 | struct { 656 | CGContextRef context; 657 | double x; 658 | double y; 659 | double width; 660 | double height; 661 | } draw; 662 | struct { 663 | NPBool hasFocus; 664 | } focus; 665 | struct { 666 | NPNSString *text; 667 | } text; 668 | } data; 669 | } NPCocoaEvent; 670 | 671 | #ifndef NP_NO_CARBON 672 | /* Non-standard event types that can be passed to HandleEvent */ 673 | enum NPEventType { 674 | NPEventType_GetFocusEvent = (osEvt + 16), 675 | NPEventType_LoseFocusEvent, 676 | NPEventType_AdjustCursorEvent, 677 | NPEventType_MenuCommandEvent, 678 | NPEventType_ClippingChangedEvent, 679 | NPEventType_ScrollingBeginsEvent = 1000, 680 | NPEventType_ScrollingEndsEvent 681 | }; 682 | #endif /* NP_NO_CARBON */ 683 | 684 | #endif /* XP_MACOSX */ 685 | 686 | /* 687 | * Values for mode passed to NPP_New: 688 | */ 689 | #define NP_EMBED 1 690 | #define NP_FULL 2 691 | 692 | /* 693 | * Values for stream type passed to NPP_NewStream: 694 | */ 695 | #define NP_NORMAL 1 696 | #define NP_SEEK 2 697 | #define NP_ASFILE 3 698 | #define NP_ASFILEONLY 4 699 | 700 | #define NP_MAXREADY (((unsigned)(~0)<<1)>>1) 701 | 702 | /* 703 | * Flags for NPP_ClearSiteData. 704 | */ 705 | #define NP_CLEAR_ALL 0 706 | #define NP_CLEAR_CACHE (1 << 0) 707 | 708 | #if !defined(__LP64__) 709 | #if defined(XP_MACOSX) 710 | #pragma options align=reset 711 | #endif 712 | #endif /* __LP64__ */ 713 | 714 | /*----------------------------------------------------------------------*/ 715 | /* Error and Reason Code definitions */ 716 | /*----------------------------------------------------------------------*/ 717 | 718 | /* 719 | * Values of type NPError: 720 | */ 721 | #define NPERR_BASE 0 722 | #define NPERR_NO_ERROR (NPERR_BASE + 0) 723 | #define NPERR_GENERIC_ERROR (NPERR_BASE + 1) 724 | #define NPERR_INVALID_INSTANCE_ERROR (NPERR_BASE + 2) 725 | #define NPERR_INVALID_FUNCTABLE_ERROR (NPERR_BASE + 3) 726 | #define NPERR_MODULE_LOAD_FAILED_ERROR (NPERR_BASE + 4) 727 | #define NPERR_OUT_OF_MEMORY_ERROR (NPERR_BASE + 5) 728 | #define NPERR_INVALID_PLUGIN_ERROR (NPERR_BASE + 6) 729 | #define NPERR_INVALID_PLUGIN_DIR_ERROR (NPERR_BASE + 7) 730 | #define NPERR_INCOMPATIBLE_VERSION_ERROR (NPERR_BASE + 8) 731 | #define NPERR_INVALID_PARAM (NPERR_BASE + 9) 732 | #define NPERR_INVALID_URL (NPERR_BASE + 10) 733 | #define NPERR_FILE_NOT_FOUND (NPERR_BASE + 11) 734 | #define NPERR_NO_DATA (NPERR_BASE + 12) 735 | #define NPERR_STREAM_NOT_SEEKABLE (NPERR_BASE + 13) 736 | #define NPERR_TIME_RANGE_NOT_SUPPORTED (NPERR_BASE + 14) 737 | #define NPERR_MALFORMED_SITE (NPERR_BASE + 15) 738 | 739 | /* 740 | * Values of type NPReason: 741 | */ 742 | #define NPRES_BASE 0 743 | #define NPRES_DONE (NPRES_BASE + 0) 744 | #define NPRES_NETWORK_ERR (NPRES_BASE + 1) 745 | #define NPRES_USER_BREAK (NPRES_BASE + 2) 746 | 747 | /* 748 | * Don't use these obsolete error codes any more. 749 | */ 750 | #define NP_NOERR NP_NOERR_is_obsolete_use_NPERR_NO_ERROR 751 | #define NP_EINVAL NP_EINVAL_is_obsolete_use_NPERR_GENERIC_ERROR 752 | #define NP_EABORT NP_EABORT_is_obsolete_use_NPRES_USER_BREAK 753 | 754 | /* 755 | * Version feature information 756 | */ 757 | #define NPVERS_HAS_STREAMOUTPUT 8 758 | #define NPVERS_HAS_NOTIFICATION 9 759 | #define NPVERS_HAS_LIVECONNECT 9 760 | #define NPVERS_68K_HAS_LIVECONNECT 11 761 | #define NPVERS_HAS_WINDOWLESS 11 762 | #define NPVERS_HAS_XPCONNECT_SCRIPTING 13 763 | #define NPVERS_HAS_NPRUNTIME_SCRIPTING 14 764 | #define NPVERS_HAS_FORM_VALUES 15 765 | #define NPVERS_HAS_POPUPS_ENABLED_STATE 16 766 | #define NPVERS_HAS_RESPONSE_HEADERS 17 767 | #define NPVERS_HAS_NPOBJECT_ENUM 18 768 | #define NPVERS_HAS_PLUGIN_THREAD_ASYNC_CALL 19 769 | #define NPVERS_HAS_ALL_NETWORK_STREAMS 20 770 | #define NPVERS_HAS_URL_AND_AUTH_INFO 21 771 | #define NPVERS_HAS_PRIVATE_MODE 22 772 | #define NPVERS_MACOSX_HAS_COCOA_EVENTS 23 773 | #define NPVERS_HAS_ADVANCED_KEY_HANDLING 25 774 | #define NPVERS_HAS_URL_REDIRECT_HANDLING 26 775 | #define NPVERS_HAS_CLEAR_SITE_DATA 27 776 | 777 | /*----------------------------------------------------------------------*/ 778 | /* Function Prototypes */ 779 | /*----------------------------------------------------------------------*/ 780 | 781 | #if defined(__OS2__) 782 | #define NP_LOADDS _System 783 | #else 784 | #define NP_LOADDS 785 | #endif 786 | 787 | #ifdef __cplusplus 788 | extern "C" { 789 | #endif 790 | 791 | /* NPP_* functions are provided by the plugin and called by the navigator. */ 792 | 793 | #if defined(XP_UNIX) 794 | const char* NPP_GetMIMEDescription(void); 795 | #endif 796 | 797 | NPError NP_LOADDS NPP_New(NPMIMEType pluginType, NPP instance, 798 | uint16_t mode, int16_t argc, char* argn[], 799 | char* argv[], NPSavedData* saved); 800 | NPError NP_LOADDS NPP_Destroy(NPP instance, NPSavedData** save); 801 | NPError NP_LOADDS NPP_SetWindow(NPP instance, NPWindow* window); 802 | NPError NP_LOADDS NPP_NewStream(NPP instance, NPMIMEType type, 803 | NPStream* stream, NPBool seekable, 804 | uint16_t* stype); 805 | NPError NP_LOADDS NPP_DestroyStream(NPP instance, NPStream* stream, 806 | NPReason reason); 807 | int32_t NP_LOADDS NPP_WriteReady(NPP instance, NPStream* stream); 808 | int32_t NP_LOADDS NPP_Write(NPP instance, NPStream* stream, int32_t offset, 809 | int32_t len, void* buffer); 810 | void NP_LOADDS NPP_StreamAsFile(NPP instance, NPStream* stream, 811 | const char* fname); 812 | void NP_LOADDS NPP_Print(NPP instance, NPPrint* platformPrint); 813 | int16_t NP_LOADDS NPP_HandleEvent(NPP instance, void* event); 814 | void NP_LOADDS NPP_URLNotify(NPP instance, const char* url, 815 | NPReason reason, void* notifyData); 816 | NPError NP_LOADDS NPP_GetValue(NPP instance, NPPVariable variable, void *value); 817 | NPError NP_LOADDS NPP_SetValue(NPP instance, NPNVariable variable, void *value); 818 | NPBool NP_LOADDS NPP_GotFocus(NPP instance, NPFocusDirection direction); 819 | void NP_LOADDS NPP_LostFocus(NPP instance); 820 | void NP_LOADDS NPP_URLRedirectNotify(NPP instance, const char* url, int32_t status, void* notifyData); 821 | NPError NP_LOADDS NPP_ClearSiteData(const char* site, uint64_t flags, uint64_t maxAge); 822 | char** NP_LOADDS NPP_GetSitesWithData(void); 823 | 824 | /* NPN_* functions are provided by the navigator and called by the plugin. */ 825 | void NP_LOADDS NPN_Version(int* plugin_major, int* plugin_minor, 826 | int* netscape_major, int* netscape_minor); 827 | NPError NP_LOADDS NPN_GetURLNotify(NPP instance, const char* url, 828 | const char* target, void* notifyData); 829 | NPError NP_LOADDS NPN_GetURL(NPP instance, const char* url, 830 | const char* target); 831 | NPError NP_LOADDS NPN_PostURLNotify(NPP instance, const char* url, 832 | const char* target, uint32_t len, 833 | const char* buf, NPBool file, 834 | void* notifyData); 835 | NPError NP_LOADDS NPN_PostURL(NPP instance, const char* url, 836 | const char* target, uint32_t len, 837 | const char* buf, NPBool file); 838 | NPError NP_LOADDS NPN_RequestRead(NPStream* stream, NPByteRange* rangeList); 839 | NPError NP_LOADDS NPN_NewStream(NPP instance, NPMIMEType type, 840 | const char* target, NPStream** stream); 841 | int32_t NP_LOADDS NPN_Write(NPP instance, NPStream* stream, int32_t len, 842 | void* buffer); 843 | NPError NP_LOADDS NPN_DestroyStream(NPP instance, NPStream* stream, 844 | NPReason reason); 845 | void NP_LOADDS NPN_Status(NPP instance, const char* message); 846 | const char* NP_LOADDS NPN_UserAgent(NPP instance); 847 | void* NP_LOADDS NPN_MemAlloc(uint32_t size); 848 | void NP_LOADDS NPN_MemFree(void* ptr); 849 | uint32_t NP_LOADDS NPN_MemFlush(uint32_t size); 850 | void NP_LOADDS NPN_ReloadPlugins(NPBool reloadPages); 851 | NPError NP_LOADDS NPN_GetValue(NPP instance, NPNVariable variable, 852 | void *value); 853 | NPError NP_LOADDS NPN_SetValue(NPP instance, NPPVariable variable, 854 | void *value); 855 | void NP_LOADDS NPN_InvalidateRect(NPP instance, NPRect *invalidRect); 856 | void NP_LOADDS NPN_InvalidateRegion(NPP instance, 857 | NPRegion invalidRegion); 858 | void NP_LOADDS NPN_ForceRedraw(NPP instance); 859 | void NP_LOADDS NPN_PushPopupsEnabledState(NPP instance, NPBool enabled); 860 | void NP_LOADDS NPN_PopPopupsEnabledState(NPP instance); 861 | void NP_LOADDS NPN_PluginThreadAsyncCall(NPP instance, 862 | void (*func) (void *), 863 | void *userData); 864 | NPError NP_LOADDS NPN_GetValueForURL(NPP instance, NPNURLVariable variable, 865 | const char *url, char **value, 866 | uint32_t *len); 867 | NPError NP_LOADDS NPN_SetValueForURL(NPP instance, NPNURLVariable variable, 868 | const char *url, const char *value, 869 | uint32_t len); 870 | NPError NP_LOADDS NPN_GetAuthenticationInfo(NPP instance, 871 | const char *protocol, 872 | const char *host, int32_t port, 873 | const char *scheme, 874 | const char *realm, 875 | char **username, uint32_t *ulen, 876 | char **password, 877 | uint32_t *plen); 878 | uint32_t NP_LOADDS NPN_ScheduleTimer(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)); 879 | void NP_LOADDS NPN_UnscheduleTimer(NPP instance, uint32_t timerID); 880 | NPError NP_LOADDS NPN_PopUpContextMenu(NPP instance, NPMenu* menu); 881 | NPBool NP_LOADDS NPN_ConvertPoint(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); 882 | NPBool NP_LOADDS NPN_HandleEvent(NPP instance, void *event, NPBool handled); 883 | NPBool NP_LOADDS NPN_UnfocusInstance(NPP instance, NPFocusDirection direction); 884 | void NP_LOADDS NPN_URLRedirectResponse(NPP instance, void* notifyData, NPBool allow); 885 | 886 | #ifdef __cplusplus 887 | } /* end extern "C" */ 888 | #endif 889 | 890 | #endif /* RC_INVOKED */ 891 | #if defined(__OS2__) 892 | #pragma pack() 893 | #endif 894 | 895 | #endif /* npapi_h_ */ 896 | -------------------------------------------------------------------------------- /plugin/npapi-headers/npfunctions.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * Netscape Communications Corporation. 19 | * Portions created by the Initial Developer are Copyright (C) 1998 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * 24 | * Alternatively, the contents of this file may be used under the terms of 25 | * either the GNU General Public License Version 2 or later (the "GPL"), or 26 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 27 | * in which case the provisions of the GPL or the LGPL are applicable instead 28 | * of those above. If you wish to allow use of your version of this file only 29 | * under the terms of either the GPL or the LGPL, and not to allow others to 30 | * use your version of this file under the terms of the MPL, indicate your 31 | * decision by deleting the provisions above and replace them with the notice 32 | * and other provisions required by the GPL or the LGPL. If you do not delete 33 | * the provisions above, a recipient may use your version of this file under 34 | * the terms of any one of the MPL, the GPL or the LGPL. 35 | * 36 | * ***** END LICENSE BLOCK ***** */ 37 | 38 | #ifndef npfunctions_h_ 39 | #define npfunctions_h_ 40 | 41 | #ifdef __OS2__ 42 | #pragma pack(1) 43 | #define NP_LOADDS _System 44 | #else 45 | #define NP_LOADDS 46 | #endif 47 | 48 | #include "npapi.h" 49 | #include "npruntime.h" 50 | 51 | typedef NPError (* NP_LOADDS NPP_NewProcPtr)(NPMIMEType pluginType, NPP instance, uint16_t mode, int16_t argc, char* argn[], char* argv[], NPSavedData* saved); 52 | typedef NPError (* NP_LOADDS NPP_DestroyProcPtr)(NPP instance, NPSavedData** save); 53 | typedef NPError (* NP_LOADDS NPP_SetWindowProcPtr)(NPP instance, NPWindow* window); 54 | typedef NPError (* NP_LOADDS NPP_NewStreamProcPtr)(NPP instance, NPMIMEType type, NPStream* stream, NPBool seekable, uint16_t* stype); 55 | typedef NPError (* NP_LOADDS NPP_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason); 56 | typedef int32_t (* NP_LOADDS NPP_WriteReadyProcPtr)(NPP instance, NPStream* stream); 57 | typedef int32_t (* NP_LOADDS NPP_WriteProcPtr)(NPP instance, NPStream* stream, int32_t offset, int32_t len, void* buffer); 58 | typedef void (* NP_LOADDS NPP_StreamAsFileProcPtr)(NPP instance, NPStream* stream, const char* fname); 59 | typedef void (* NP_LOADDS NPP_PrintProcPtr)(NPP instance, NPPrint* platformPrint); 60 | typedef int16_t (* NP_LOADDS NPP_HandleEventProcPtr)(NPP instance, void* event); 61 | typedef void (* NP_LOADDS NPP_URLNotifyProcPtr)(NPP instance, const char* url, NPReason reason, void* notifyData); 62 | /* Any NPObjects returned to the browser via NPP_GetValue should be retained 63 | by the plugin on the way out. The browser is responsible for releasing. */ 64 | typedef NPError (* NP_LOADDS NPP_GetValueProcPtr)(NPP instance, NPPVariable variable, void *ret_value); 65 | typedef NPError (* NP_LOADDS NPP_SetValueProcPtr)(NPP instance, NPNVariable variable, void *value); 66 | typedef NPBool (* NP_LOADDS NPP_GotFocusPtr)(NPP instance, NPFocusDirection direction); 67 | typedef void (* NP_LOADDS NPP_LostFocusPtr)(NPP instance); 68 | typedef void (* NP_LOADDS NPP_URLRedirectNotifyPtr)(NPP instance, const char* url, int32_t status, void* notifyData); 69 | typedef NPError (* NP_LOADDS NPP_ClearSiteDataPtr)(const char* site, uint64_t flags, uint64_t maxAge); 70 | typedef char** (* NP_LOADDS NPP_GetSitesWithDataPtr)(void); 71 | 72 | typedef NPError (*NPN_GetValueProcPtr)(NPP instance, NPNVariable variable, void *ret_value); 73 | typedef NPError (*NPN_SetValueProcPtr)(NPP instance, NPPVariable variable, void *value); 74 | typedef NPError (*NPN_GetURLNotifyProcPtr)(NPP instance, const char* url, const char* window, void* notifyData); 75 | typedef NPError (*NPN_PostURLNotifyProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file, void* notifyData); 76 | typedef NPError (*NPN_GetURLProcPtr)(NPP instance, const char* url, const char* window); 77 | typedef NPError (*NPN_PostURLProcPtr)(NPP instance, const char* url, const char* window, uint32_t len, const char* buf, NPBool file); 78 | typedef NPError (*NPN_RequestReadProcPtr)(NPStream* stream, NPByteRange* rangeList); 79 | typedef NPError (*NPN_NewStreamProcPtr)(NPP instance, NPMIMEType type, const char* window, NPStream** stream); 80 | typedef int32_t (*NPN_WriteProcPtr)(NPP instance, NPStream* stream, int32_t len, void* buffer); 81 | typedef NPError (*NPN_DestroyStreamProcPtr)(NPP instance, NPStream* stream, NPReason reason); 82 | typedef void (*NPN_StatusProcPtr)(NPP instance, const char* message); 83 | /* Browser manages the lifetime of the buffer returned by NPN_UserAgent, don't 84 | depend on it sticking around and don't free it. */ 85 | typedef const char* (*NPN_UserAgentProcPtr)(NPP instance); 86 | typedef void* (*NPN_MemAllocProcPtr)(uint32_t size); 87 | typedef void (*NPN_MemFreeProcPtr)(void* ptr); 88 | typedef uint32_t (*NPN_MemFlushProcPtr)(uint32_t size); 89 | typedef void (*NPN_ReloadPluginsProcPtr)(NPBool reloadPages); 90 | typedef void* (*NPN_GetJavaEnvProcPtr)(void); 91 | typedef void* (*NPN_GetJavaPeerProcPtr)(NPP instance); 92 | typedef void (*NPN_InvalidateRectProcPtr)(NPP instance, NPRect *rect); 93 | typedef void (*NPN_InvalidateRegionProcPtr)(NPP instance, NPRegion region); 94 | typedef void (*NPN_ForceRedrawProcPtr)(NPP instance); 95 | typedef NPIdentifier (*NPN_GetStringIdentifierProcPtr)(const NPUTF8* name); 96 | typedef void (*NPN_GetStringIdentifiersProcPtr)(const NPUTF8** names, int32_t nameCount, NPIdentifier* identifiers); 97 | typedef NPIdentifier (*NPN_GetIntIdentifierProcPtr)(int32_t intid); 98 | typedef bool (*NPN_IdentifierIsStringProcPtr)(NPIdentifier identifier); 99 | typedef NPUTF8* (*NPN_UTF8FromIdentifierProcPtr)(NPIdentifier identifier); 100 | typedef int32_t (*NPN_IntFromIdentifierProcPtr)(NPIdentifier identifier); 101 | typedef NPObject* (*NPN_CreateObjectProcPtr)(NPP npp, NPClass *aClass); 102 | typedef NPObject* (*NPN_RetainObjectProcPtr)(NPObject *obj); 103 | typedef void (*NPN_ReleaseObjectProcPtr)(NPObject *obj); 104 | typedef bool (*NPN_InvokeProcPtr)(NPP npp, NPObject* obj, NPIdentifier methodName, const NPVariant *args, uint32_t argCount, NPVariant *result); 105 | typedef bool (*NPN_InvokeDefaultProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result); 106 | typedef bool (*NPN_EvaluateProcPtr)(NPP npp, NPObject *obj, NPString *script, NPVariant *result); 107 | typedef bool (*NPN_GetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, NPVariant *result); 108 | typedef bool (*NPN_SetPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName, const NPVariant *value); 109 | typedef bool (*NPN_RemovePropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName); 110 | typedef bool (*NPN_HasPropertyProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName); 111 | typedef bool (*NPN_HasMethodProcPtr)(NPP npp, NPObject *obj, NPIdentifier propertyName); 112 | typedef void (*NPN_ReleaseVariantValueProcPtr)(NPVariant *variant); 113 | typedef void (*NPN_SetExceptionProcPtr)(NPObject *obj, const NPUTF8 *message); 114 | typedef void (*NPN_PushPopupsEnabledStateProcPtr)(NPP npp, NPBool enabled); 115 | typedef void (*NPN_PopPopupsEnabledStateProcPtr)(NPP npp); 116 | typedef bool (*NPN_EnumerateProcPtr)(NPP npp, NPObject *obj, NPIdentifier **identifier, uint32_t *count); 117 | typedef void (*NPN_PluginThreadAsyncCallProcPtr)(NPP instance, void (*func)(void *), void *userData); 118 | typedef bool (*NPN_ConstructProcPtr)(NPP npp, NPObject* obj, const NPVariant *args, uint32_t argCount, NPVariant *result); 119 | typedef NPError (*NPN_GetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, char **value, uint32_t *len); 120 | typedef NPError (*NPN_SetValueForURLPtr)(NPP npp, NPNURLVariable variable, const char *url, const char *value, uint32_t len); 121 | typedef NPError (*NPN_GetAuthenticationInfoPtr)(NPP npp, const char *protocol, const char *host, int32_t port, const char *scheme, const char *realm, char **username, uint32_t *ulen, char **password, uint32_t *plen); 122 | typedef uint32_t (*NPN_ScheduleTimerPtr)(NPP instance, uint32_t interval, NPBool repeat, void (*timerFunc)(NPP npp, uint32_t timerID)); 123 | typedef void (*NPN_UnscheduleTimerPtr)(NPP instance, uint32_t timerID); 124 | typedef NPError (*NPN_PopUpContextMenuPtr)(NPP instance, NPMenu* menu); 125 | typedef NPBool (*NPN_ConvertPointPtr)(NPP instance, double sourceX, double sourceY, NPCoordinateSpace sourceSpace, double *destX, double *destY, NPCoordinateSpace destSpace); 126 | typedef NPBool (*NPN_HandleEventPtr)(NPP instance, void *event, NPBool handled); 127 | typedef NPBool (*NPN_UnfocusInstancePtr)(NPP instance, NPFocusDirection direction); 128 | typedef void (*NPN_URLRedirectResponsePtr)(NPP instance, void* notifyData, NPBool allow); 129 | 130 | typedef struct _NPPluginFuncs { 131 | uint16_t size; 132 | uint16_t version; 133 | NPP_NewProcPtr newp; 134 | NPP_DestroyProcPtr destroy; 135 | NPP_SetWindowProcPtr setwindow; 136 | NPP_NewStreamProcPtr newstream; 137 | NPP_DestroyStreamProcPtr destroystream; 138 | NPP_StreamAsFileProcPtr asfile; 139 | NPP_WriteReadyProcPtr writeready; 140 | NPP_WriteProcPtr write; 141 | NPP_PrintProcPtr print; 142 | NPP_HandleEventProcPtr event; 143 | NPP_URLNotifyProcPtr urlnotify; 144 | void* javaClass; 145 | NPP_GetValueProcPtr getvalue; 146 | NPP_SetValueProcPtr setvalue; 147 | NPP_GotFocusPtr gotfocus; 148 | NPP_LostFocusPtr lostfocus; 149 | NPP_URLRedirectNotifyPtr urlredirectnotify; 150 | NPP_ClearSiteDataPtr clearsitedata; 151 | NPP_GetSitesWithDataPtr getsiteswithdata; 152 | } NPPluginFuncs; 153 | 154 | typedef struct _NPNetscapeFuncs { 155 | uint16_t size; 156 | uint16_t version; 157 | NPN_GetURLProcPtr geturl; 158 | NPN_PostURLProcPtr posturl; 159 | NPN_RequestReadProcPtr requestread; 160 | NPN_NewStreamProcPtr newstream; 161 | NPN_WriteProcPtr write; 162 | NPN_DestroyStreamProcPtr destroystream; 163 | NPN_StatusProcPtr status; 164 | NPN_UserAgentProcPtr uagent; 165 | NPN_MemAllocProcPtr memalloc; 166 | NPN_MemFreeProcPtr memfree; 167 | NPN_MemFlushProcPtr memflush; 168 | NPN_ReloadPluginsProcPtr reloadplugins; 169 | NPN_GetJavaEnvProcPtr getJavaEnv; 170 | NPN_GetJavaPeerProcPtr getJavaPeer; 171 | NPN_GetURLNotifyProcPtr geturlnotify; 172 | NPN_PostURLNotifyProcPtr posturlnotify; 173 | NPN_GetValueProcPtr getvalue; 174 | NPN_SetValueProcPtr setvalue; 175 | NPN_InvalidateRectProcPtr invalidaterect; 176 | NPN_InvalidateRegionProcPtr invalidateregion; 177 | NPN_ForceRedrawProcPtr forceredraw; 178 | NPN_GetStringIdentifierProcPtr getstringidentifier; 179 | NPN_GetStringIdentifiersProcPtr getstringidentifiers; 180 | NPN_GetIntIdentifierProcPtr getintidentifier; 181 | NPN_IdentifierIsStringProcPtr identifierisstring; 182 | NPN_UTF8FromIdentifierProcPtr utf8fromidentifier; 183 | NPN_IntFromIdentifierProcPtr intfromidentifier; 184 | NPN_CreateObjectProcPtr createobject; 185 | NPN_RetainObjectProcPtr retainobject; 186 | NPN_ReleaseObjectProcPtr releaseobject; 187 | NPN_InvokeProcPtr invoke; 188 | NPN_InvokeDefaultProcPtr invokeDefault; 189 | NPN_EvaluateProcPtr evaluate; 190 | NPN_GetPropertyProcPtr getproperty; 191 | NPN_SetPropertyProcPtr setproperty; 192 | NPN_RemovePropertyProcPtr removeproperty; 193 | NPN_HasPropertyProcPtr hasproperty; 194 | NPN_HasMethodProcPtr hasmethod; 195 | NPN_ReleaseVariantValueProcPtr releasevariantvalue; 196 | NPN_SetExceptionProcPtr setexception; 197 | NPN_PushPopupsEnabledStateProcPtr pushpopupsenabledstate; 198 | NPN_PopPopupsEnabledStateProcPtr poppopupsenabledstate; 199 | NPN_EnumerateProcPtr enumerate; 200 | NPN_PluginThreadAsyncCallProcPtr pluginthreadasynccall; 201 | NPN_ConstructProcPtr construct; 202 | NPN_GetValueForURLPtr getvalueforurl; 203 | NPN_SetValueForURLPtr setvalueforurl; 204 | NPN_GetAuthenticationInfoPtr getauthenticationinfo; 205 | NPN_ScheduleTimerPtr scheduletimer; 206 | NPN_UnscheduleTimerPtr unscheduletimer; 207 | NPN_PopUpContextMenuPtr popupcontextmenu; 208 | NPN_ConvertPointPtr convertpoint; 209 | NPN_HandleEventPtr handleevent; 210 | NPN_UnfocusInstancePtr unfocusinstance; 211 | NPN_URLRedirectResponsePtr urlredirectresponse; 212 | } NPNetscapeFuncs; 213 | 214 | #ifdef XP_MACOSX 215 | /* 216 | * Mac OS X version(s) of NP_GetMIMEDescription(const char *) 217 | * These can be called to retreive MIME information from the plugin dynamically 218 | * 219 | * Note: For compatibility with Quicktime, BPSupportedMIMEtypes is another way 220 | * to get mime info from the plugin only on OSX and may not be supported 221 | * in furture version -- use NP_GetMIMEDescription instead 222 | */ 223 | enum 224 | { 225 | kBPSupportedMIMETypesStructVers_1 = 1 226 | }; 227 | typedef struct _BPSupportedMIMETypes 228 | { 229 | SInt32 structVersion; /* struct version */ 230 | Handle typeStrings; /* STR# formated handle, allocated by plug-in */ 231 | Handle infoStrings; /* STR# formated handle, allocated by plug-in */ 232 | } BPSupportedMIMETypes; 233 | OSErr BP_GetSupportedMIMETypes(BPSupportedMIMETypes *mimeInfo, UInt32 flags); 234 | #define NP_GETMIMEDESCRIPTION_NAME "NP_GetMIMEDescription" 235 | typedef const char* (*NP_GetMIMEDescriptionProcPtr)(void); 236 | typedef OSErr (*BP_GetSupportedMIMETypesProcPtr)(BPSupportedMIMETypes*, UInt32); 237 | #endif 238 | 239 | #if defined(_WIN32) 240 | #define OSCALL WINAPI 241 | #else 242 | #if defined(__OS2__) 243 | #define OSCALL _System 244 | #else 245 | #define OSCALL 246 | #endif 247 | #endif 248 | 249 | #if defined(XP_UNIX) 250 | /* GCC 3.3 and later support the visibility attribute. */ 251 | #if defined(__GNUC__) && ((__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)) 252 | #define NP_VISIBILITY_DEFAULT __attribute__((visibility("default"))) 253 | #elif defined(__SUNPRO_C) || defined(__SUNPRO_CC) 254 | #define NP_VISIBILITY_DEFAULT __global 255 | #else 256 | #define NP_VISIBILITY_DEFAULT 257 | #endif 258 | #define NP_EXPORT(__type) NP_VISIBILITY_DEFAULT __type 259 | #endif 260 | 261 | #if defined(_WIN32) || defined (__OS2__) 262 | #ifdef __cplusplus 263 | extern "C" { 264 | #endif 265 | /* plugin meta member functions */ 266 | #if defined(__OS2__) 267 | typedef struct _NPPluginData { /* Alternate OS2 Plugin interface */ 268 | char *pMimeTypes; 269 | char *pFileExtents; 270 | char *pFileOpenTemplate; 271 | char *pProductName; 272 | char *pProductDescription; 273 | unsigned long dwProductVersionMS; 274 | unsigned long dwProductVersionLS; 275 | } NPPluginData; 276 | typedef NPError (*NP_GetPluginDataFunc)(NPPluginData*); 277 | NPError OSCALL NP_GetPluginData(NPPluginData * pPluginData); 278 | #endif 279 | typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*); 280 | NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* pFuncs); 281 | typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*); 282 | NPError OSCALL NP_Initialize(NPNetscapeFuncs* bFuncs); 283 | typedef NPError (*NP_ShutdownFunc)(void); 284 | NPError OSCALL NP_Shutdown(void); 285 | typedef const char* (*NP_GetMIMEDescriptionFunc)(void); 286 | const char* NP_GetMIMEDescription(void); 287 | #ifdef __cplusplus 288 | } 289 | #endif 290 | #endif 291 | 292 | #if defined(__OS2__) 293 | #pragma pack() 294 | #endif 295 | 296 | #ifdef XP_UNIX 297 | #ifdef __cplusplus 298 | extern "C" { 299 | #endif 300 | typedef char* (*NP_GetPluginVersionFunc)(void); 301 | NP_EXPORT(char*) NP_GetPluginVersion(void); 302 | typedef const char* (*NP_GetMIMEDescriptionFunc)(void); 303 | NP_EXPORT(const char*) NP_GetMIMEDescription(void); 304 | #ifdef XP_MACOSX 305 | typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*); 306 | NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs); 307 | typedef NPError (*NP_GetEntryPointsFunc)(NPPluginFuncs*); 308 | NP_EXPORT(NPError) NP_GetEntryPoints(NPPluginFuncs* pFuncs); 309 | #else 310 | typedef NPError (*NP_InitializeFunc)(NPNetscapeFuncs*, NPPluginFuncs*); 311 | NP_EXPORT(NPError) NP_Initialize(NPNetscapeFuncs* bFuncs, NPPluginFuncs* pFuncs); 312 | #endif 313 | typedef NPError (*NP_ShutdownFunc)(void); 314 | NP_EXPORT(NPError) NP_Shutdown(void); 315 | typedef NPError (*NP_GetValueFunc)(void *, NPPVariable, void *); 316 | NP_EXPORT(NPError) NP_GetValue(void *future, NPPVariable aVariable, void *aValue); 317 | #ifdef __cplusplus 318 | } 319 | #endif 320 | #endif 321 | 322 | #endif /* npfunctions_h_ */ 323 | -------------------------------------------------------------------------------- /plugin/npapi-headers/npruntime.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 | /* 3 | * Copyright (c) 2004, Apple Computer, Inc. and The Mozilla Foundation. 4 | * All rights reserved. 5 | * 6 | * Redistribution and use in source and binary forms, with or without 7 | * modification, are permitted provided that the following conditions are 8 | * met: 9 | * 10 | * 1. Redistributions of source code must retain the above copyright 11 | * notice, this list of conditions and the following disclaimer. 12 | * 2. Redistributions in binary form must reproduce the above copyright 13 | * notice, this list of conditions and the following disclaimer in the 14 | * documentation and/or other materials provided with the distribution. 15 | * 3. Neither the names of Apple Computer, Inc. ("Apple") or The Mozilla 16 | * Foundation ("Mozilla") nor the names of their contributors may be used 17 | * to endorse or promote products derived from this software without 18 | * specific prior written permission. 19 | * 20 | * THIS SOFTWARE IS PROVIDED BY APPLE, MOZILLA AND THEIR CONTRIBUTORS "AS 21 | * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 23 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE, MOZILLA OR 24 | * THEIR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 26 | * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | */ 33 | #ifndef _NP_RUNTIME_H_ 34 | #define _NP_RUNTIME_H_ 35 | 36 | #ifdef __cplusplus 37 | extern "C" { 38 | #endif 39 | 40 | #include "nptypes.h" 41 | 42 | /* 43 | This API is used to facilitate binding code written in C to script 44 | objects. The API in this header does not assume the presence of a 45 | user agent. That is, it can be used to bind C code to scripting 46 | environments outside of the context of a user agent. 47 | 48 | However, the normal use of the this API is in the context of a 49 | scripting environment running in a browser or other user agent. 50 | In particular it is used to support the extended Netscape 51 | script-ability API for plugins (NP-SAP). NP-SAP is an extension 52 | of the Netscape plugin API. As such we have adopted the use of 53 | the "NP" prefix for this API. 54 | 55 | The following NP{N|P}Variables were added to the Netscape plugin 56 | API (in npapi.h): 57 | 58 | NPNVWindowNPObject 59 | NPNVPluginElementNPObject 60 | NPPVpluginScriptableNPObject 61 | 62 | These variables are exposed through NPN_GetValue() and 63 | NPP_GetValue() (respectively) and are used to establish the 64 | initial binding between the user agent and native code. The DOM 65 | objects in the user agent can be examined and manipulated using 66 | the NPN_ functions that operate on NPObjects described in this 67 | header. 68 | 69 | To the extent possible the assumptions about the scripting 70 | language used by the scripting environment have been minimized. 71 | */ 72 | 73 | #define NP_BEGIN_MACRO do { 74 | #define NP_END_MACRO } while (0) 75 | 76 | /* 77 | Objects (non-primitive data) passed between 'C' and script is 78 | always wrapped in an NPObject. The 'interface' of an NPObject is 79 | described by an NPClass. 80 | */ 81 | typedef struct NPObject NPObject; 82 | typedef struct NPClass NPClass; 83 | 84 | typedef char NPUTF8; 85 | typedef struct _NPString { 86 | const NPUTF8 *UTF8Characters; 87 | uint32_t UTF8Length; 88 | } NPString; 89 | 90 | typedef enum { 91 | NPVariantType_Void, 92 | NPVariantType_Null, 93 | NPVariantType_Bool, 94 | NPVariantType_Int32, 95 | NPVariantType_Double, 96 | NPVariantType_String, 97 | NPVariantType_Object 98 | } NPVariantType; 99 | 100 | typedef struct _NPVariant { 101 | NPVariantType type; 102 | union { 103 | bool boolValue; 104 | int32_t intValue; 105 | double doubleValue; 106 | NPString stringValue; 107 | NPObject *objectValue; 108 | } value; 109 | } NPVariant; 110 | 111 | /* 112 | NPN_ReleaseVariantValue is called on all 'out' parameters 113 | references. Specifically it is to be called on variants that own 114 | their value, as is the case with all non-const NPVariant* 115 | arguments after a successful call to any methods (except this one) 116 | in this API. 117 | 118 | After calling NPN_ReleaseVariantValue, the type of the variant 119 | will be NPVariantType_Void. 120 | */ 121 | void NPN_ReleaseVariantValue(NPVariant *variant); 122 | 123 | #define NPVARIANT_IS_VOID(_v) ((_v).type == NPVariantType_Void) 124 | #define NPVARIANT_IS_NULL(_v) ((_v).type == NPVariantType_Null) 125 | #define NPVARIANT_IS_BOOLEAN(_v) ((_v).type == NPVariantType_Bool) 126 | #define NPVARIANT_IS_INT32(_v) ((_v).type == NPVariantType_Int32) 127 | #define NPVARIANT_IS_DOUBLE(_v) ((_v).type == NPVariantType_Double) 128 | #define NPVARIANT_IS_STRING(_v) ((_v).type == NPVariantType_String) 129 | #define NPVARIANT_IS_OBJECT(_v) ((_v).type == NPVariantType_Object) 130 | 131 | #define NPVARIANT_TO_BOOLEAN(_v) ((_v).value.boolValue) 132 | #define NPVARIANT_TO_INT32(_v) ((_v).value.intValue) 133 | #define NPVARIANT_TO_DOUBLE(_v) ((_v).value.doubleValue) 134 | #define NPVARIANT_TO_STRING(_v) ((_v).value.stringValue) 135 | #define NPVARIANT_TO_OBJECT(_v) ((_v).value.objectValue) 136 | 137 | #define VOID_TO_NPVARIANT(_v) \ 138 | NP_BEGIN_MACRO \ 139 | (_v).type = NPVariantType_Void; \ 140 | (_v).value.objectValue = NULL; \ 141 | NP_END_MACRO 142 | 143 | #define NULL_TO_NPVARIANT(_v) \ 144 | NP_BEGIN_MACRO \ 145 | (_v).type = NPVariantType_Null; \ 146 | (_v).value.objectValue = NULL; \ 147 | NP_END_MACRO 148 | 149 | #define BOOLEAN_TO_NPVARIANT(_val, _v) \ 150 | NP_BEGIN_MACRO \ 151 | (_v).type = NPVariantType_Bool; \ 152 | (_v).value.boolValue = !!(_val); \ 153 | NP_END_MACRO 154 | 155 | #define INT32_TO_NPVARIANT(_val, _v) \ 156 | NP_BEGIN_MACRO \ 157 | (_v).type = NPVariantType_Int32; \ 158 | (_v).value.intValue = _val; \ 159 | NP_END_MACRO 160 | 161 | #define DOUBLE_TO_NPVARIANT(_val, _v) \ 162 | NP_BEGIN_MACRO \ 163 | (_v).type = NPVariantType_Double; \ 164 | (_v).value.doubleValue = _val; \ 165 | NP_END_MACRO 166 | 167 | #define STRINGZ_TO_NPVARIANT(_val, _v) \ 168 | NP_BEGIN_MACRO \ 169 | (_v).type = NPVariantType_String; \ 170 | NPString str = { _val, (uint32_t)(strlen(_val)) }; \ 171 | (_v).value.stringValue = str; \ 172 | NP_END_MACRO 173 | 174 | #define STRINGN_TO_NPVARIANT(_val, _len, _v) \ 175 | NP_BEGIN_MACRO \ 176 | (_v).type = NPVariantType_String; \ 177 | NPString str = { _val, (uint32_t)(_len) }; \ 178 | (_v).value.stringValue = str; \ 179 | NP_END_MACRO 180 | 181 | #define OBJECT_TO_NPVARIANT(_val, _v) \ 182 | NP_BEGIN_MACRO \ 183 | (_v).type = NPVariantType_Object; \ 184 | (_v).value.objectValue = _val; \ 185 | NP_END_MACRO 186 | 187 | 188 | /* 189 | Type mappings (JavaScript types have been used for illustration 190 | purposes): 191 | 192 | JavaScript to C (NPVariant with type:) 193 | undefined NPVariantType_Void 194 | null NPVariantType_Null 195 | Boolean NPVariantType_Bool 196 | Number NPVariantType_Double or NPVariantType_Int32 197 | String NPVariantType_String 198 | Object NPVariantType_Object 199 | 200 | C (NPVariant with type:) to JavaScript 201 | NPVariantType_Void undefined 202 | NPVariantType_Null null 203 | NPVariantType_Bool Boolean 204 | NPVariantType_Int32 Number 205 | NPVariantType_Double Number 206 | NPVariantType_String String 207 | NPVariantType_Object Object 208 | */ 209 | 210 | typedef void *NPIdentifier; 211 | 212 | /* 213 | NPObjects have methods and properties. Methods and properties are 214 | identified with NPIdentifiers. These identifiers may be reflected 215 | in script. NPIdentifiers can be either strings or integers, IOW, 216 | methods and properties can be identified by either strings or 217 | integers (i.e. foo["bar"] vs foo[1]). NPIdentifiers can be 218 | compared using ==. In case of any errors, the requested 219 | NPIdentifier(s) will be NULL. NPIdentifier lifetime is controlled 220 | by the browser. Plugins do not need to worry about memory management 221 | with regards to NPIdentifiers. 222 | */ 223 | NPIdentifier NPN_GetStringIdentifier(const NPUTF8 *name); 224 | void NPN_GetStringIdentifiers(const NPUTF8 **names, int32_t nameCount, 225 | NPIdentifier *identifiers); 226 | NPIdentifier NPN_GetIntIdentifier(int32_t intid); 227 | bool NPN_IdentifierIsString(NPIdentifier identifier); 228 | 229 | /* 230 | The NPUTF8 returned from NPN_UTF8FromIdentifier SHOULD be freed. 231 | */ 232 | NPUTF8 *NPN_UTF8FromIdentifier(NPIdentifier identifier); 233 | 234 | /* 235 | Get the integer represented by identifier. If identifier is not an 236 | integer identifier, the behaviour is undefined. 237 | */ 238 | int32_t NPN_IntFromIdentifier(NPIdentifier identifier); 239 | 240 | /* 241 | NPObject behavior is implemented using the following set of 242 | callback functions. 243 | 244 | The NPVariant *result argument of these functions (where 245 | applicable) should be released using NPN_ReleaseVariantValue(). 246 | */ 247 | typedef NPObject *(*NPAllocateFunctionPtr)(NPP npp, NPClass *aClass); 248 | typedef void (*NPDeallocateFunctionPtr)(NPObject *npobj); 249 | typedef void (*NPInvalidateFunctionPtr)(NPObject *npobj); 250 | typedef bool (*NPHasMethodFunctionPtr)(NPObject *npobj, NPIdentifier name); 251 | typedef bool (*NPInvokeFunctionPtr)(NPObject *npobj, NPIdentifier name, 252 | const NPVariant *args, uint32_t argCount, 253 | NPVariant *result); 254 | typedef bool (*NPInvokeDefaultFunctionPtr)(NPObject *npobj, 255 | const NPVariant *args, 256 | uint32_t argCount, 257 | NPVariant *result); 258 | typedef bool (*NPHasPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name); 259 | typedef bool (*NPGetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, 260 | NPVariant *result); 261 | typedef bool (*NPSetPropertyFunctionPtr)(NPObject *npobj, NPIdentifier name, 262 | const NPVariant *value); 263 | typedef bool (*NPRemovePropertyFunctionPtr)(NPObject *npobj, 264 | NPIdentifier name); 265 | typedef bool (*NPEnumerationFunctionPtr)(NPObject *npobj, NPIdentifier **value, 266 | uint32_t *count); 267 | typedef bool (*NPConstructFunctionPtr)(NPObject *npobj, 268 | const NPVariant *args, 269 | uint32_t argCount, 270 | NPVariant *result); 271 | 272 | /* 273 | NPObjects returned by create, retain, invoke, and getProperty pass 274 | a reference count to the caller. That is, the callee adds a 275 | reference count which passes to the caller. It is the caller's 276 | responsibility to release the returned object. 277 | 278 | NPInvokeFunctionPtr function may return 0 to indicate a void 279 | result. 280 | 281 | NPInvalidateFunctionPtr is called by the scripting environment 282 | when the native code is shutdown. Any attempt to message a 283 | NPObject instance after the invalidate callback has been 284 | called will result in undefined behavior, even if the native code 285 | is still retaining those NPObject instances. (The runtime 286 | will typically return immediately, with 0 or NULL, from an attempt 287 | to dispatch to a NPObject, but this behavior should not be 288 | depended upon.) 289 | 290 | The NPEnumerationFunctionPtr function may pass an array of 291 | NPIdentifiers back to the caller. The callee allocs the memory of 292 | the array using NPN_MemAlloc(), and it's the caller's responsibility 293 | to release it using NPN_MemFree(). 294 | */ 295 | struct NPClass 296 | { 297 | uint32_t structVersion; 298 | NPAllocateFunctionPtr allocate; 299 | NPDeallocateFunctionPtr deallocate; 300 | NPInvalidateFunctionPtr invalidate; 301 | NPHasMethodFunctionPtr hasMethod; 302 | NPInvokeFunctionPtr invoke; 303 | NPInvokeDefaultFunctionPtr invokeDefault; 304 | NPHasPropertyFunctionPtr hasProperty; 305 | NPGetPropertyFunctionPtr getProperty; 306 | NPSetPropertyFunctionPtr setProperty; 307 | NPRemovePropertyFunctionPtr removeProperty; 308 | NPEnumerationFunctionPtr enumerate; 309 | NPConstructFunctionPtr construct; 310 | }; 311 | 312 | #define NP_CLASS_STRUCT_VERSION 3 313 | 314 | #define NP_CLASS_STRUCT_VERSION_ENUM 2 315 | #define NP_CLASS_STRUCT_VERSION_CTOR 3 316 | 317 | #define NP_CLASS_STRUCT_VERSION_HAS_ENUM(npclass) \ 318 | ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_ENUM) 319 | 320 | #define NP_CLASS_STRUCT_VERSION_HAS_CTOR(npclass) \ 321 | ((npclass)->structVersion >= NP_CLASS_STRUCT_VERSION_CTOR) 322 | 323 | struct NPObject { 324 | NPClass *_class; 325 | uint32_t referenceCount; 326 | /* 327 | * Additional space may be allocated here by types of NPObjects 328 | */ 329 | }; 330 | 331 | /* 332 | If the class has an allocate function, NPN_CreateObject invokes 333 | that function, otherwise a NPObject is allocated and 334 | returned. This method will initialize the referenceCount member of 335 | the NPObject to 1. 336 | */ 337 | NPObject *NPN_CreateObject(NPP npp, NPClass *aClass); 338 | 339 | /* 340 | Increment the NPObject's reference count. 341 | */ 342 | NPObject *NPN_RetainObject(NPObject *npobj); 343 | 344 | /* 345 | Decremented the NPObject's reference count. If the reference 346 | count goes to zero, the class's destroy function is invoke if 347 | specified, otherwise the object is freed directly. 348 | */ 349 | void NPN_ReleaseObject(NPObject *npobj); 350 | 351 | /* 352 | Functions to access script objects represented by NPObject. 353 | 354 | Calls to script objects are synchronous. If a function returns a 355 | value, it will be supplied via the result NPVariant 356 | argument. Successful calls will return true, false will be 357 | returned in case of an error. 358 | 359 | Calls made from plugin code to script must be made from the thread 360 | on which the plugin was initialized. 361 | */ 362 | 363 | bool NPN_Invoke(NPP npp, NPObject *npobj, NPIdentifier methodName, 364 | const NPVariant *args, uint32_t argCount, NPVariant *result); 365 | bool NPN_InvokeDefault(NPP npp, NPObject *npobj, const NPVariant *args, 366 | uint32_t argCount, NPVariant *result); 367 | bool NPN_Evaluate(NPP npp, NPObject *npobj, NPString *script, 368 | NPVariant *result); 369 | bool NPN_GetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, 370 | NPVariant *result); 371 | bool NPN_SetProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName, 372 | const NPVariant *value); 373 | bool NPN_RemoveProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); 374 | bool NPN_HasProperty(NPP npp, NPObject *npobj, NPIdentifier propertyName); 375 | bool NPN_HasMethod(NPP npp, NPObject *npobj, NPIdentifier methodName); 376 | bool NPN_Enumerate(NPP npp, NPObject *npobj, NPIdentifier **identifier, 377 | uint32_t *count); 378 | bool NPN_Construct(NPP npp, NPObject *npobj, const NPVariant *args, 379 | uint32_t argCount, NPVariant *result); 380 | 381 | /* 382 | NPN_SetException may be called to trigger a script exception upon 383 | return from entry points into NPObjects. Typical usage: 384 | 385 | NPN_SetException (npobj, message); 386 | */ 387 | void NPN_SetException(NPObject *npobj, const NPUTF8 *message); 388 | 389 | #ifdef __cplusplus 390 | } 391 | #endif 392 | 393 | #endif 394 | -------------------------------------------------------------------------------- /plugin/npapi-headers/nptypes.h: -------------------------------------------------------------------------------- 1 | /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 2 | /* ***** BEGIN LICENSE BLOCK ***** 3 | * Version: MPL 1.1/GPL 2.0/LGPL 2.1 4 | * 5 | * The contents of this file are subject to the Mozilla Public License Version 6 | * 1.1 (the "License"); you may not use this file except in compliance with 7 | * the License. You may obtain a copy of the License at 8 | * http://www.mozilla.org/MPL/ 9 | * 10 | * Software distributed under the License is distributed on an "AS IS" basis, 11 | * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 12 | * for the specific language governing rights and limitations under the 13 | * License. 14 | * 15 | * The Original Code is mozilla.org code. 16 | * 17 | * The Initial Developer of the Original Code is 18 | * mozilla.org. 19 | * Portions created by the Initial Developer are Copyright (C) 2004 20 | * the Initial Developer. All Rights Reserved. 21 | * 22 | * Contributor(s): 23 | * Johnny Stenback (Original author) 24 | * 25 | * Alternatively, the contents of this file may be used under the terms of 26 | * either the GNU General Public License Version 2 or later (the "GPL"), or 27 | * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 28 | * in which case the provisions of the GPL or the LGPL are applicable instead 29 | * of those above. If you wish to allow use of your version of this file only 30 | * under the terms of either the GPL or the LGPL, and not to allow others to 31 | * use your version of this file under the terms of the MPL, indicate your 32 | * decision by deleting the provisions above and replace them with the notice 33 | * and other provisions required by the GPL or the LGPL. If you do not delete 34 | * the provisions above, a recipient may use your version of this file under 35 | * the terms of any one of the MPL, the GPL or the LGPL. 36 | * 37 | * ***** END LICENSE BLOCK ***** */ 38 | 39 | #ifndef nptypes_h_ 40 | #define nptypes_h_ 41 | 42 | /* 43 | * Header file for ensuring that C99 types ([u]int32_t, [u]int64_t and bool) and 44 | * true/false macros are available. 45 | */ 46 | 47 | #if defined(WIN32) || defined(OS2) 48 | /* 49 | * Win32 and OS/2 don't know C99, so define [u]int_16/32/64 here. The bool 50 | * is predefined tho, both in C and C++. 51 | */ 52 | typedef short int16_t; 53 | typedef unsigned short uint16_t; 54 | typedef int int32_t; 55 | typedef unsigned int uint32_t; 56 | typedef long long int64_t; 57 | typedef unsigned long long uint64_t; 58 | #elif defined(_AIX) || defined(__sun) || defined(__osf__) || defined(IRIX) || defined(HPUX) 59 | /* 60 | * AIX and SunOS ship a inttypes.h header that defines [u]int32_t, 61 | * but not bool for C. 62 | */ 63 | #include 64 | 65 | #ifndef __cplusplus 66 | typedef int bool; 67 | #define true 1 68 | #define false 0 69 | #endif 70 | #elif defined(bsdi) || defined(FREEBSD) || defined(OPENBSD) 71 | /* 72 | * BSD/OS, FreeBSD, and OpenBSD ship sys/types.h that define int32_t and 73 | * u_int32_t. 74 | */ 75 | #include 76 | 77 | /* 78 | * BSD/OS ships no header that defines uint32_t, nor bool (for C) 79 | */ 80 | #if defined(bsdi) 81 | typedef u_int32_t uint32_t; 82 | typedef u_int64_t uint64_t; 83 | 84 | #if !defined(__cplusplus) 85 | typedef int bool; 86 | #define true 1 87 | #define false 0 88 | #endif 89 | #else 90 | /* 91 | * FreeBSD and OpenBSD define uint32_t and bool. 92 | */ 93 | #include 94 | #include 95 | #endif 96 | #elif defined(BEOS) 97 | #include 98 | #else 99 | /* 100 | * For those that ship a standard C99 stdint.h header file, include 101 | * it. Can't do the same for stdbool.h tho, since some systems ship 102 | * with a stdbool.h file that doesn't compile! 103 | */ 104 | #include 105 | 106 | #ifndef __cplusplus 107 | #if !defined(__GNUC__) || (__GNUC__ > 2 || __GNUC_MINOR__ > 95) 108 | #include 109 | #else 110 | /* 111 | * GCC 2.91 can't deal with a typedef for bool, but a #define 112 | * works. 113 | */ 114 | #define bool int 115 | #define true 1 116 | #define false 0 117 | #endif 118 | #endif 119 | #endif 120 | 121 | #endif /* nptypes_h_ */ 122 | -------------------------------------------------------------------------------- /plugin/util.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2010 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #ifndef INCLUDED_UTIL_H_ 6 | #define INCLUDED_UTIL_H_ 7 | 8 | #define DISALLOW_COPY_AND_ASSIGN(Class) \ 9 | Class(const Class&); \ 10 | void operator=(const Class&); 11 | 12 | #define G_FORWARD_DECLARE(GTypeName) typedef struct _ ## GTypeName GTypeName 13 | 14 | #endif // INCLUDED_UTIL_H_ 15 | -------------------------------------------------------------------------------- /plugin/xembed_container_plugin.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2011 David Benjamin. All rights reserved. 2 | // Use of this source code is governed by an MIT-style license that can be 3 | // found in the LICENSE file. 4 | 5 | #include "npapi-cxx/browser.h" 6 | #include "npapi-cxx/plugin.h" 7 | #include "npapi-cxx/plugin_instance.h" 8 | #include "npapi-cxx/script_object.h" 9 | #include "npapi-cxx/scoped_npobject.h" 10 | #include "util.h" 11 | 12 | namespace { 13 | 14 | NPIdentifier g_identifier_windowId = 0; 15 | 16 | class XEmbedContainerPlugin; 17 | class XEmbedContainerInstance; 18 | class XEmbedContainerObject; 19 | 20 | class XEmbedContainerPlugin : public npapi::Plugin { 21 | public: 22 | NPError Init(); 23 | 24 | const char* GetMIMEDescription(); 25 | NPError GetValue(NPPVariable variable, void *value); 26 | npapi::PluginInstance* CreateInstance(NPMIMEType plugin_type, NPP npp, 27 | uint16_t mode, 28 | int16_t argc, 29 | char *argn[], char *argv[], 30 | NPSavedData* saved, 31 | NPError* error); 32 | }; 33 | 34 | class XEmbedContainerInstance : public npapi::PluginInstance { 35 | public: 36 | XEmbedContainerInstance(NPP npp); 37 | 38 | long window_id() { return window_id_; } 39 | 40 | NPError SetWindow(NPWindow* window); 41 | NPError GetValue(NPPVariable variable, void* value); 42 | private: 43 | long window_id_; 44 | npapi::scoped_npobject script_object_; 45 | }; 46 | 47 | class XEmbedContainerObject : public npapi::ScriptObject { 48 | public: 49 | XEmbedContainerInstance* plugin_instance(); 50 | bool HasProperty(NPIdentifier name); 51 | bool GetProperty(NPIdentifier name, NPVariant *result); 52 | bool Enumerate(NPIdentifier **identifiers, uint32_t *identifier_count); 53 | private: 54 | friend class npapi::ScriptObject; 55 | XEmbedContainerObject(NPP npp); 56 | ~XEmbedContainerObject(); 57 | }; 58 | 59 | ////////////////////////////////////// 60 | // XEmbedContainerPlugin 61 | ////////////////////////////////////// 62 | 63 | NPError XEmbedContainerPlugin::Init() { 64 | int major_version, minor_version; 65 | NPN_Version(NULL, NULL, &major_version, &minor_version); 66 | 67 | // Require NPRuntime. 68 | if (minor_version < NPVERS_HAS_NPRUNTIME_SCRIPTING) 69 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 70 | 71 | // Require XEmbed support. 72 | NPBool has_xembed = false; 73 | NPError err = NPN_GetValue(NULL, NPNVSupportsXEmbedBool, &has_xembed); 74 | if (err != NPERR_NO_ERROR || !has_xembed) 75 | return NPERR_INCOMPATIBLE_VERSION_ERROR; 76 | 77 | // Initialize one identifier I care about. 78 | g_identifier_windowId = NPN_GetStringIdentifier("windowId"); 79 | 80 | return NPERR_NO_ERROR; 81 | } 82 | 83 | const char* XEmbedContainerPlugin::GetMIMEDescription() { 84 | return "application/x-embedded-emacs-container:" 85 | ":" 86 | "XEmbed container (Embedded Emacs)"; 87 | } 88 | 89 | NPError XEmbedContainerPlugin::GetValue(NPPVariable variable, void *value) { 90 | NPError err = NPERR_NO_ERROR; 91 | switch (variable) { 92 | case NPPVpluginNameString: 93 | *reinterpret_cast(value) = 94 | "Embedded Emacs - XEmbed container"; 95 | break; 96 | case NPPVpluginDescriptionString: 97 | *reinterpret_cast(value) = 98 | "Dummy plugin that exports X11 window id for a" 99 | " trusted plugin to embed Emacs into."; 100 | break; 101 | default: 102 | err = Plugin::GetValue(variable, value); 103 | } 104 | return err; 105 | } 106 | 107 | npapi::PluginInstance* XEmbedContainerPlugin::CreateInstance( 108 | NPMIMEType plugin_type, NPP npp, uint16_t mode, 109 | int16_t argc, char *argn[], char *argv[], 110 | NPSavedData* saved, 111 | NPError* error) { 112 | // TODO: Pass some of these arguments in?? 113 | return new XEmbedContainerInstance(npp); 114 | } 115 | 116 | 117 | ////////////////////////////////////// 118 | // XEmbedContainerInstance 119 | ////////////////////////////////////// 120 | 121 | XEmbedContainerInstance::XEmbedContainerInstance(NPP npp) 122 | : PluginInstance(npp), 123 | window_id_(0) { 124 | } 125 | 126 | NPError XEmbedContainerInstance::SetWindow(NPWindow* window) { 127 | long window_id = reinterpret_cast(window->window); 128 | if (!window_id_) { 129 | window_id_ = window_id; 130 | } else { 131 | // This really shouldn't happen. 132 | if (window_id != window_id_) 133 | return NPERR_GENERIC_ERROR; 134 | } 135 | return NPERR_NO_ERROR; 136 | } 137 | 138 | NPError XEmbedContainerInstance::GetValue(NPPVariable variable, void* value) { 139 | NPError err = NPERR_NO_ERROR; 140 | switch (variable) { 141 | case NPPVpluginNeedsXEmbed: 142 | *reinterpret_cast(value) = true; 143 | break; 144 | case NPPVpluginScriptableNPObject: { 145 | if (!script_object_.get()) { 146 | script_object_.reset(XEmbedContainerObject::Create(npp())); 147 | } 148 | *reinterpret_cast(value) = 149 | static_cast(script_object_.get()); 150 | break; 151 | } 152 | default: 153 | err = PluginInstance::GetValue(variable, value); 154 | } 155 | return err; 156 | } 157 | 158 | ////////////////////////////////////// 159 | // XEmbedContainerObject 160 | ////////////////////////////////////// 161 | 162 | XEmbedContainerInstance* XEmbedContainerObject::plugin_instance() { 163 | return static_cast( 164 | npapi::ScriptObject::plugin_instance()); 165 | } 166 | 167 | bool XEmbedContainerObject::HasProperty(NPIdentifier name) { 168 | return (name == g_identifier_windowId); 169 | } 170 | 171 | bool XEmbedContainerObject::GetProperty(NPIdentifier name, NPVariant *result) { 172 | if (!HasProperty(name)) 173 | return false; 174 | if (!plugin_instance()) 175 | return false; 176 | INT32_TO_NPVARIANT(plugin_instance()->window_id(), *result); 177 | return true; 178 | } 179 | 180 | bool XEmbedContainerObject::Enumerate(NPIdentifier **identifiers, 181 | uint32_t *identifier_count) { 182 | NPIdentifier* properties = static_cast( 183 | NPN_MemAlloc(sizeof(NPIdentifier))); 184 | if (!properties) return false; 185 | 186 | properties[0] = g_identifier_windowId; 187 | 188 | *identifiers = properties; 189 | *identifier_count = 1; 190 | return true; 191 | } 192 | 193 | XEmbedContainerObject::XEmbedContainerObject(NPP npp) 194 | : npapi::ScriptObject(npp) { 195 | } 196 | 197 | XEmbedContainerObject::~XEmbedContainerObject() { 198 | } 199 | 200 | } // namespace 201 | 202 | namespace npapi { 203 | Plugin* Plugin::CreatePlugin() { 204 | return new XEmbedContainerPlugin(); 205 | } 206 | } // namespace npapi 207 | --------------------------------------------------------------------------------