Permalink
Browse files

initial commit, minimal functionnality

  • Loading branch information...
0 parents commit 73e1e6643d343dc19515ddc6bda764703c677303 @olalonde committed Mar 1, 2011
Showing with 185 additions and 0 deletions.
  1. +26 −0 LICENSE
  2. +18 −0 README.md
  3. +1 −0 TUTORIAL.md
  4. +1 −0 build/.gitignore
  5. +7 −0 js/demo.js
  6. +115 −0 src/node_gtknotify.cpp
  7. +17 −0 wscript
@@ -0,0 +1,26 @@
+Copyright 2011, Olivier Lalonde. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ copyright notice, this list of conditions and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+ * Neither the name of Olivier Lalonde nor the names of its
+ contributors may be used to endorse or promote products derived
+ from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,18 @@
+THIS IS A WORK IN PROGRESS!!!
+
+---
+
+Part 1 (V8 extension) available here: [http://syskall.com/how-to-roll-out-your-own-javascript-api-with](http://syskall.com/how-to-roll-out-your-own-javascript-api-with)
+
+## Install ##
+
+ node-waf configure && node-waf build
+
+## References ##
+
+https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native-extensions/
+https://github.com/pquerna/node-extension-examples
+http://code.google.com/apis/v8/embed.html
+irc.freenode.org #v8 #node.js
+https://github.com/ncb000gt/node.bcrypt.js
+https://github.com/joyent/node
@@ -0,0 +1 @@
+Part 1 (V8 extension) available here: [http://syskall.com/how-to-roll-out-your-own-javascript-api-with](http://syskall.com/how-to-roll-out-your-own-javascript-api-with)
@@ -0,0 +1 @@
+*
@@ -0,0 +1,7 @@
+var notify = require("../build/default/gtknotify.node"); // node.js stuff
+
+var notification = new notify.Notification();
+//notification.icon = "terminal";
+//notification.title = "Notification title";
+notification.text = "Some text here...";
+console.log(notification.send("yippi"));
@@ -0,0 +1,115 @@
+#include <v8.h>
+#include <node.h>
+// We need those two libraries for the GTK+ notification
+#include <gtkmm.h>
+#include <libnotifymm.h>
+
+// V8 documentation:
+// Context: a context is an execution environment that allows separate, unrelated, JavaScript applications to run in a single instance of V8.
+// must be explicitly specified
+// Handles: Local (deleted when scope deleted),
+// Persistent (deleted manually),
+// Handle (parent class)
+// Handle scope: a container that holds lots of handles.
+// when handle scope's destructor is called (implicitly called when ~ called) all handles created within that scope are removed
+// Template: A template is a blueprint for JavaScript functions and objects in a context (i.e. Google Chrome's DOM)
+// Function template: A function template is the blueprint for a single function.
+// Object templates: Each function template has an associated object template. accessors/interceptor C++ callbacks
+
+// todo: remove "using namespace" for less confusion node vs v8
+using namespace node;
+using namespace v8;
+
+class Gtknotify : node::ObjectWrap {
+ private:
+ public:
+ // Function template for notification()
+ static v8::Persistent<FunctionTemplate> persistent_function_template;
+
+ // Node: the target is the "module", it's where your extension will be loaded into
+ static void Init(Handle<Object> target) {
+ /* V8 PART */
+ // This scope will contain all local handles within this method (in other words, it will contain local_function_template)
+ v8::HandleScope scope;
+
+ // Map our function template to the C++ New() method
+ // Need to create local template first because that's what v8::FunctionTemplate::New returns
+
+ // irc convo
+ // <oli> anyone knows why you need to make a local function template before making it persistent?
+ // Local<FunctionTemplate> t = FunctionTemplate::New(New); s_ct = Persistent<FunctionTemplate>::New(t);
+ // <bradleymeck> oli mainly just readability, you *could* cast it as you assign to t
+ // <oli> I assume v8::FunctionTemplate::New returns a local handle
+ // <bradleymeck> it does, when im talking about casting here im talking about the v8 api cast not c cast
+ v8::Local<FunctionTemplate> local_function_template = v8::FunctionTemplate::New(New);
+
+ // Make our local function template persistent
+ persistent_function_template = v8::Persistent<FunctionTemplate>::New(local_function_template);
+ /* V8 doc:
+ Each JavaScript point object keeps a reference to the C++ object for which it is a wrapper with an internal field.
+ These fields are so named because they cannot be accessed from within JavaScript, they can only be accessed from C++ code.
+ An object can have any number of internal fields, the number of internal fields is set on the object template as follows: */
+ persistent_function_template->InstanceTemplate()->SetInternalFieldCount(1);
+ // Map our function template to a Javascript function name, so it can be called from Javascript: Notification()
+ persistent_function_template->SetClassName(v8::String::NewSymbol("Notification"));
+
+ /* NODE PART */
+ // Arguments: function template, JS method name, C++ method
+ // @see https://github.com/joyent/node/blob/v0.2.0/src/node.h#L34
+ NODE_SET_PROTOTYPE_METHOD(persistent_function_template, "send", Send);
+ // Add .notification() to the target, "module" so we expose our function as module.notification();
+ target->Set(String::NewSymbol("Notification"), persistent_function_template->GetFunction());
+ }
+
+ Gtknotify() {}
+
+ ~Gtknotify() {}
+
+ // Called when our class is created (constructor function)
+ // Instantiates C++ object
+ static Handle<Value> New(const Arguments& args) {
+ HandleScope scope;
+ Gtknotify* gtknotify_instance = new Gtknotify();
+ // stores a reference to the C++ Gtknotify object inside the args.This() value
+ gtknotify_instance->Wrap(args.This()); // Inherited from node::ObjectWrap
+
+ // Once it is wrapped up, it returns args.This(), which is just like what the new operator does in Javascript,
+ // returning the this as an object.
+ return args.This();
+ }
+
+ static v8::Handle<Value> Send(const Arguments& args) {
+ v8::HandleScope scope;
+ // Extract C++ object reference from JS object passed as args.This()
+ Gtknotify* gtknotify_instance = node::ObjectWrap::Unwrap<Gtknotify>(args.This());
+ // todo: notify_instance->send();
+ //Local<String> result = String::New("Hello World");
+
+ // LIBNOTIFY
+ v8::String::Utf8Value str(args[0]); // Convert first argument to V8 String
+
+ Notify::init("Basic");
+ // Arguments: title, content, icon
+ Notify::Notification n("Alert", *str, "terminal"); // *str = c string
+ // Display notification
+ n.show();
+
+ return v8::Boolean::New(true);
+ }
+};
+
+// Why this?
+v8::Persistent<FunctionTemplate> Gtknotify::persistent_function_template;
+
+/* Thats it for actual interfacing with v8, finally we need to let Node.js know how to dynamically load our code.
+ Because a Node.js extension can be loaded at runtime from a shared object, we need a symbol that the dlsym function can find,
+ so we do the following: */
+// @see http://www.freebsd.org/cgi/man.cgi?query=dlsym
+// cause of name mangling in C++, we use extern C here
+extern "C" {
+ static void init(Handle<Object> target) {
+ Gtknotify::Init(target);
+ }
+ // @see http://github.com/ry/node/blob/v0.2.0/src/node.h#L101
+ NODE_MODULE(gtknotify, init);
+}
@@ -0,0 +1,17 @@
+def set_options(opt):
+ opt.tool_options("compiler_cxx")
+
+def configure(conf):
+ conf.check_tool("compiler_cxx")
+ conf.check_tool("node_addon")
+ # @oli
+ conf.check_cfg(package='gtkmm-2.4', args='--cflags --libs', uselib_store='LIBGTKMM')
+ conf.check_cfg(package='libnotifymm-1.0', args='--cflags --libs', uselib_store='LIBNOTIFYMM')
+
+def build(bld):
+ obj = bld.new_task_gen("cxx", "shlib", "node_addon")
+ obj.cxxflags = ["-g", "-D_FILE_OFFSET_BITS=64", "-D_LARGEFILE_SOURCE", "-Wall"]
+ obj.target = "gtknotify"
+ obj.source = "src/node_gtknotify.cpp"
+ # @oli
+ obj.uselib = ['LIBGTKMM', 'LIBNOTIFYMM']

0 comments on commit 73e1e66

Please sign in to comment.