├── .gitmodules ├── .gitignore ├── package.json ├── index.js ├── LICENSES ├── src ├── atb.h ├── common.h ├── atb.cc └── glfw.cc ├── test ├── test.js └── test_atb.js ├── binding.gyp └── README.md /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "deps"] 2 | path = deps 3 | url = https://github.com/mikeseven/node-native-graphics-deps.git 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_glfw.node 2 | .cproject,.project 3 | .cproject 4 | .project 5 | .lock-wscript 6 | build 7 | .DS_Store 8 | Debug 9 | node-glfw.iml 10 | node_modules 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-glfw", 3 | "version": "0.4.6", 4 | "description": "A NodeJS wrapper around GLFW 3.x library", 5 | "main": "index.js", 6 | "author": "Mikael Bourges-Sevenier ", 7 | "keywords": [ 8 | "glfw", 9 | "opengl", 10 | "3d", 11 | "graphics" 12 | ], 13 | "maintainers": [ 14 | { 15 | "name": "Mikael Bourges-Sevenier", 16 | "email": "mikeseven@gmail.com", 17 | "twitter": "msevenier" 18 | } 19 | ], 20 | "license" : "BSD-3-Clause", 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/mikeseven/node-glfw.git" 24 | }, 25 | "directories": { 26 | "src": "src", 27 | "lib": "lib", 28 | "test": "test" 29 | }, 30 | "engines": { 31 | "node": ">=3.0.0" 32 | }, 33 | "scripts": { 34 | "install": "node-gyp rebuild" 35 | }, 36 | "dependencies": { 37 | "bindings": "^1.2.1", 38 | "nan": "^2.1.0" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var GLFW = module.exports = require('bindings')('glfw'); 2 | 3 | // Easy event emitter based event loop. Started automatically when the first 4 | // listener is added. 5 | var events; 6 | Object.defineProperty(GLFW, 'events', { 7 | get: function () { 8 | if (events) return events; 9 | events = new (require('events').EventEmitter); 10 | 11 | var _emit=events.emit; 12 | events.emit=function() { 13 | var args = Array.prototype.slice.call(arguments); 14 | var evt= args[1]; // args[1] is the event, args[0] is the type of event 15 | //console.log("emitting event: "+require('util').inspect(args)); 16 | if(args[0] != 'quit') { 17 | evt.preventDefault = function () {}; 18 | evt.stopPropagation = function () {}; 19 | } 20 | //_emit.apply(this,args); 21 | events.listeners(args[0]).forEach(function(listener) { 22 | listener(args[1]); 23 | }); 24 | }; 25 | return events; 26 | }, 27 | enumerable: true, 28 | configurable: true 29 | }); 30 | -------------------------------------------------------------------------------- /LICENSES: -------------------------------------------------------------------------------- 1 | This document lists all the licenses used in this node-glfw repository: 2 | 3 | - Part I - node-glfw distributed under BSD license 4 | 5 | ------------------------------------------------------------------------------ 6 | Part I - node-glfw distributed under BSD license 7 | 8 | Copyright (c) 2011-2012, Mikael Bourges-Sevenier 9 | All rights reserved. 10 | 11 | Redistribution and use in source and binary forms, with or without 12 | modification, are permitted provided that the following conditions are met: 13 | 14 | * Redistributions of source code must retain the above copyright 15 | notice, this list of conditions and the following disclaimer. 16 | * Redistributions in binary form must reproduce the above copyright 17 | notice, this list of conditions and the following disclaimer in the 18 | documentation and/or other materials provided with the distribution. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 24 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 26 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 27 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 29 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /src/atb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * atb.h 3 | * 4 | */ 5 | 6 | #ifndef ATB_H_ 7 | #define ATB_H_ 8 | 9 | #include "common.h" 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace v8; 16 | using namespace node; 17 | 18 | namespace atb { 19 | 20 | struct CB { 21 | Nan::Persistent getter, setter; 22 | uint32_t type; 23 | char *name; 24 | CB() : type(0), name(NULL) {} 25 | ~CB() { 26 | getter.Reset(); 27 | setter.Reset(); 28 | if(name) free(name); 29 | } 30 | }; 31 | 32 | class Bar : public Nan::ObjectWrap { 33 | public: 34 | static Bar *New(TwBar *bar); 35 | static NAN_MODULE_INIT(Initialize); 36 | 37 | protected: 38 | static NAN_METHOD(New); 39 | static NAN_METHOD(AddVar); 40 | static NAN_METHOD(AddSeparator); 41 | static NAN_METHOD(AddButton); 42 | static NAN_METHOD(RemoveVar); 43 | static NAN_METHOD(RemoveAllVars); 44 | 45 | virtual ~Bar (); 46 | 47 | private: 48 | Bar(Handle wrapper); 49 | static Nan::Persistent constructor_template; 50 | 51 | TwBar *bar; 52 | std::vector cbs; 53 | }; 54 | 55 | class AntTweakBar : public Nan::ObjectWrap { 56 | public: 57 | static NAN_MODULE_INIT(Initialize); 58 | 59 | protected: 60 | static NAN_METHOD(New); 61 | static NAN_METHOD(Init); 62 | static NAN_METHOD(Terminate); 63 | static NAN_METHOD(WindowSize); 64 | static NAN_METHOD(Draw); 65 | static NAN_METHOD(Define); 66 | static NAN_METHOD(DefineEnum); 67 | 68 | static NAN_METHOD(NewBar); 69 | 70 | virtual ~AntTweakBar (); 71 | 72 | private: 73 | AntTweakBar(Handle wrapper); 74 | static Nan::Persistent constructor_template; 75 | }; 76 | 77 | } // namespace atb 78 | 79 | #endif /* ATB_H_ */ 80 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* 2 | * common.h 3 | * 4 | */ 5 | 6 | #ifndef COMMON_H_ 7 | #define COMMON_H_ 8 | 9 | // OpenGL Graphics Includes 10 | #ifndef _WIN32 11 | #define GLEW_STATIC 12 | #endif 13 | #include 14 | 15 | #define GLFW_NO_GLU 16 | #define GLFW_DLL 17 | #include 18 | 19 | // NodeJS includes 20 | #include 21 | #include "nan.h" 22 | 23 | using namespace v8; 24 | 25 | namespace { 26 | #define JS_STR(...) Nan::New(__VA_ARGS__).ToLocalChecked() 27 | #define JS_INT(val) Nan::New(val) 28 | #define JS_NUM(val) Nan::New(val) 29 | #define JS_BOOL(val) (val) ? Nan::True() : Nan::False() 30 | #define JS_RETHROW(tc) v8::Local::New(tc.Exception()); 31 | 32 | #define REQ_ARGS(N) \ 33 | if (info.Length() < (N)) \ 34 | Nan::ThrowTypeError("Expected " #N " arguments"); 35 | 36 | #define REQ_STR_ARG(I, VAR) \ 37 | if (info.Length() <= (I) || !info[I]->IsString()) \ 38 | Nan::ThrowTypeError("Argument " #I " must be a string"); \ 39 | String::Utf8Value VAR(info[I]->ToString()); 40 | 41 | #define REQ_EXT_ARG(I, VAR) \ 42 | if (info.Length() <= (I) || !info[I]->IsExternal()) \ 43 | Nan::ThrowTypeError("Argument " #I " invalid"); \ 44 | Local VAR = Local::Cast(info[I]); 45 | 46 | #define REQ_FUN_ARG(I, VAR) \ 47 | if (info.Length() <= (I) || !info[I]->IsFunction()) \ 48 | Nan::ThrowTypeError("Argument " #I " must be a function"); \ 49 | Local VAR = Local::Cast(info[I]); 50 | 51 | #define REQ_ERROR_THROW(error) if (ret == error) Nan::ThrowError(String::New(#error)); 52 | 53 | } 54 | #endif /* COMMON_H_ */ 55 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | var glfw = require('../index'); 2 | var util=require('util'); 3 | var log = console.log; 4 | 5 | var version = glfw.GetVersion(); 6 | log('glfw ' + version.major + '.' + version.minor + '.' + version.rev); 7 | log('glfw version-string: ' + glfw.GetVersionString()); 8 | 9 | // Initialize GLFW 10 | if (!glfw.Init()) { 11 | log("Failed to initialize GLFW"); 12 | process.exit(-1); 13 | } 14 | 15 | // Open OpenGL window 16 | //glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3); 17 | //glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 2); 18 | //glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_ANY_PROFILE); 19 | glfw.DefaultWindowHints(); 20 | 21 | var width=640, height=480; 22 | var window=glfw.CreateWindow(width, height,"Test"); 23 | if (!window) { 24 | log("Failed to open GLFW window"); 25 | glfw.Terminate(); 26 | process.exit(-1); 27 | } 28 | 29 | glfw.MakeContextCurrent(window); 30 | 31 | glfw.SetWindowTitle("GLFW Simple Test"); 32 | 33 | // testing events 34 | glfw.events.on('keydown',function(evt) { 35 | log("[keydown] "+util.inspect(evt)); 36 | }); 37 | 38 | glfw.events.on('mousemove',function(evt) { 39 | log("[mousemove] "+evt.x+", "+evt.y); 40 | }); 41 | 42 | glfw.events.on('mousewheel',function(evt) { 43 | log("[mousewheel] "+evt.position); 44 | }); 45 | 46 | glfw.events.on('resize',function(evt){ 47 | log("[resize] "+evt.width+", "+evt.height); 48 | }); 49 | 50 | //can only be called after window creation! 51 | var glVersion_major = glfw.GetWindowAttrib(window, glfw.CONTEXT_VERSION_MAJOR); 52 | var glVersion_minor = glfw.GetWindowAttrib(window, glfw.CONTEXT_VERSION_MINOR); 53 | var glVersion_rev = glfw.GetWindowAttrib(window, glfw.CONTEXT_REVISION); 54 | var glProfile = glfw.GetWindowAttrib(window, glfw.OPENGL_PROFILE); 55 | log('GL ' + glVersion_major + '.' + glVersion_minor + '.' + glVersion_rev+ " Profile: " + glProfile); 56 | 57 | // Enable vertical sync (on cards that support it) 58 | glfw.SwapInterval(0 /*1*/); // 0 for vsync off 59 | 60 | var start = glfw.GetTime(); 61 | while(!glfw.WindowShouldClose(window) && !glfw.GetKey(window, glfw.KEY_ESCAPE)) { 62 | // Get window size (may be different than the requested size) 63 | var wsize = glfw.GetFramebufferSize(window); 64 | if(wsize) log("FB size: "+wsize.width+', '+wsize.height); 65 | 66 | glfw.testScene(wsize.width, wsize.height); 67 | 68 | // Swap buffers 69 | glfw.SwapBuffers(window); 70 | glfw.PollEvents(); 71 | 72 | } 73 | 74 | // Close OpenGL window and terminate GLFW 75 | glfw.DestroyWindow(window); 76 | glfw.Terminate(); 77 | 78 | process.exit(0); 79 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | { 2 | 'variables': { 3 | 'platform': '<(OS)', 4 | }, 5 | 'conditions': [ 6 | # Replace gyp platform with node platform, blech 7 | ['platform == "mac"', {'variables': { 8 | 'platform': 'darwin', 9 | 'ANTTWEAKBAR_ROOT': '/usr/local/Cellar/anttweakbar/1.16', 10 | }}], 11 | ['platform == "win"', {'variables': {'platform': 'win32'}}], 12 | ], 13 | 'targets': [ 14 | { 15 | 'target_name': 'glfw', 16 | 'defines': [ 17 | 'VERSION=0.4.6', 18 | ], 19 | 'sources': [ 20 | 'src/atb.cc', 21 | 'src/glfw.cc' 22 | ], 23 | 'include_dirs': [ 24 | " 4 | #include 5 | using namespace std; 6 | 7 | namespace atb { 8 | Nan::Persistent AntTweakBar::constructor_template; 9 | 10 | #define DEFINE_ATB_CONSTANT(constant) \ 11 | NODE_DEFINE_CONSTANT_VALUE(ctor->InstanceTemplate(), "TYPE_" #constant, TW_TYPE_##constant); 12 | 13 | NAN_MODULE_INIT(AntTweakBar::Initialize) 14 | { 15 | Nan::HandleScope scope; 16 | 17 | Local ctor = Nan::New(AntTweakBar::New); 18 | ctor->InstanceTemplate()->SetInternalFieldCount(1); 19 | ctor->SetClassName(JS_STR("AntTweakBar")); 20 | 21 | Nan::SetPrototypeMethod(ctor, "Init", Init); 22 | Nan::SetPrototypeMethod(ctor, "Terminate", Terminate); 23 | Nan::SetPrototypeMethod(ctor, "WindowSize", WindowSize); 24 | Nan::SetPrototypeMethod(ctor, "Draw", Draw); 25 | Nan::SetPrototypeMethod(ctor, "NewBar", NewBar); 26 | Nan::SetPrototypeMethod(ctor, "Define", Define); 27 | Nan::SetPrototypeMethod(ctor, "DefineEnum", DefineEnum); 28 | 29 | #define NODE_DEFINE_CONSTANT_VALUE(target, name, value) \ 30 | (target)->Set(JS_STR(name), \ 31 | Nan::New(value), \ 32 | static_cast(v8::ReadOnly|v8::DontDelete)) 33 | 34 | DEFINE_ATB_CONSTANT(CHAR); 35 | DEFINE_ATB_CONSTANT(INT8); 36 | DEFINE_ATB_CONSTANT(UINT8); 37 | DEFINE_ATB_CONSTANT(INT16); 38 | DEFINE_ATB_CONSTANT(UINT16); 39 | DEFINE_ATB_CONSTANT(INT32); 40 | DEFINE_ATB_CONSTANT(UINT32); 41 | DEFINE_ATB_CONSTANT(FLOAT); 42 | DEFINE_ATB_CONSTANT(DOUBLE); 43 | 44 | DEFINE_ATB_CONSTANT(COLOR32); 45 | DEFINE_ATB_CONSTANT(COLOR3F); 46 | DEFINE_ATB_CONSTANT(COLOR4F); 47 | DEFINE_ATB_CONSTANT(QUAT4F); 48 | DEFINE_ATB_CONSTANT(QUAT4D); 49 | DEFINE_ATB_CONSTANT(DIR3F); 50 | DEFINE_ATB_CONSTANT(DIR3D); 51 | 52 | //DEFINE_ATB_CONSTANT(CDSTRING); 53 | 54 | constructor_template.Reset(ctor->GetFunction()); 55 | Nan::Set(target, JS_STR("AntTweakBar"), ctor->GetFunction()); 56 | } 57 | 58 | NAN_METHOD(AntTweakBar::New) { 59 | if (!info.IsConstructCall()) 60 | return Nan::ThrowTypeError("Constructor cannot be called as a function."); 61 | 62 | Nan::HandleScope scope; 63 | AntTweakBar *cl = new AntTweakBar(info.This()); 64 | cl->Wrap(info.This()); 65 | info.GetReturnValue().Set(info.This()); 66 | } 67 | 68 | AntTweakBar::AntTweakBar(Handle wrapper) 69 | { 70 | } 71 | 72 | AntTweakBar::~AntTweakBar () { 73 | TwTerminate(); 74 | } 75 | 76 | NAN_METHOD(AntTweakBar::Init) { 77 | Nan::HandleScope scope; 78 | TwInit(TW_OPENGL, NULL); 79 | return; 80 | } 81 | 82 | NAN_METHOD(AntTweakBar::Terminate) { 83 | Nan::HandleScope scope; 84 | TwTerminate(); 85 | return; 86 | } 87 | 88 | NAN_METHOD(AntTweakBar::WindowSize) { 89 | Nan::HandleScope scope; 90 | unsigned int w=info[0]->Uint32Value(); 91 | unsigned int h=info[1]->Uint32Value(); 92 | TwWindowSize(w,h); 93 | return; 94 | } 95 | 96 | NAN_METHOD(AntTweakBar::Draw) { 97 | Nan::HandleScope scope; 98 | 99 | // save state 100 | GLint program;//, ab, eab; 101 | glGetIntegerv(GL_CURRENT_PROGRAM, &program); 102 | glUseProgram(0); 103 | 104 | // draw all AntTweakBars 105 | TwDraw(); 106 | 107 | // restore state 108 | glUseProgram(program); 109 | 110 | return; 111 | } 112 | 113 | NAN_METHOD(AntTweakBar::Define) { 114 | Nan::HandleScope scope; 115 | 116 | String::Utf8Value str(info[0]); 117 | TwDefine(*str); 118 | 119 | return; 120 | } 121 | 122 | NAN_METHOD(AntTweakBar::DefineEnum) { 123 | Nan::HandleScope scope; 124 | 125 | String::Utf8Value str(info[0]); 126 | Local arr=Local::Cast(info[1]); 127 | int num=info[2]->IsUndefined() ? arr->Length() : info[2]->Uint32Value(); 128 | 129 | TwEnumVal *vals=new TwEnumVal[num]; 130 | for(int i=0;iGet(i)->ToString()); 133 | vals[i].Label=strdup(*str); 134 | //cout<<" Adding value: "<handle()); 154 | } 155 | 156 | Nan::Persistent Bar::constructor_template; 157 | 158 | NAN_MODULE_INIT(Bar::Initialize) 159 | { 160 | Nan::HandleScope scope; 161 | 162 | Local ctor = Nan::New(Bar::New); 163 | ctor->InstanceTemplate()->SetInternalFieldCount(1); 164 | ctor->SetClassName(JS_STR("Bar")); 165 | 166 | Nan::SetPrototypeMethod(ctor, "AddVar", AddVar); 167 | Nan::SetPrototypeMethod(ctor, "RemoveVar", RemoveVar); 168 | Nan::SetPrototypeMethod(ctor, "RemoveAllVars", RemoveAllVars); 169 | Nan::SetPrototypeMethod(ctor, "AddButton", AddButton); 170 | Nan::SetPrototypeMethod(ctor, "AddSeparator", AddSeparator); 171 | 172 | constructor_template.Reset(ctor->GetFunction()); 173 | Nan::Set(target, JS_STR("Bar"), ctor->GetFunction()); 174 | } 175 | 176 | NAN_METHOD(Bar::New) { 177 | if (!info.IsConstructCall()) 178 | return Nan::ThrowTypeError("Constructor cannot be called as a function."); 179 | 180 | Nan::HandleScope scope; 181 | Bar *cl = new Bar(info.This()); 182 | cl->Wrap(info.This()); 183 | info.GetReturnValue().Set(info.This()); 184 | } 185 | 186 | Bar::Bar(Handle wrapper) : bar(NULL) 187 | { 188 | } 189 | 190 | Bar::~Bar () { 191 | for(vector::iterator it=cbs.begin();it!=cbs.end();++it) { 192 | CB *cb=*it; 193 | if(cb) delete cb; 194 | } 195 | cbs.clear(); 196 | if(bar) TwDeleteBar(bar); 197 | } 198 | 199 | Bar *Bar::New(TwBar *zbar) 200 | { 201 | 202 | Nan::HandleScope scope; 203 | 204 | Local cons = Nan::New(constructor_template); 205 | Local obj = cons->NewInstance(); 206 | 207 | Bar *v8bar = Nan::ObjectWrap::Unwrap(obj); 208 | v8bar->bar = zbar; 209 | 210 | return v8bar; 211 | } 212 | 213 | void TW_CALL SetCallback(const void *value, void *clientData) { 214 | // cout<<"in SetCallback"<(clientData); 218 | // cout<<" cb type: "<type< argv[1]; 221 | 222 | switch(cb->type) { 223 | case TW_TYPE_INT8: 224 | argv[0]=JS_INT(*static_cast(value)); 225 | break; 226 | case TW_TYPE_UINT8: 227 | argv[0]=JS_INT(*static_cast(value)); 228 | break; 229 | case TW_TYPE_INT16: 230 | argv[0]=JS_INT(*static_cast(value)); 231 | break; 232 | case TW_TYPE_UINT16: 233 | argv[0]=JS_INT(*static_cast(value)); 234 | break; 235 | case TW_TYPE_INT32: 236 | argv[0]=JS_NUM(*static_cast(value)); 237 | break; 238 | case TW_TYPE_UINT32: 239 | argv[0]=JS_NUM(*static_cast(value)); 240 | break; 241 | case TW_TYPE_FLOAT: 242 | argv[0]=JS_NUM(*static_cast(value)); 243 | break; 244 | case TW_TYPE_DOUBLE: 245 | argv[0]=JS_NUM(*static_cast(value)); 246 | break; 247 | case TW_TYPE_DIR3F: { 248 | const float *val=static_cast(value); 249 | Local arr=Nan::New(3); 250 | arr->Set(0,JS_NUM(val[0])); 251 | arr->Set(1,JS_NUM(val[1])); 252 | arr->Set(2,JS_NUM(val[2])); 253 | argv[0]=arr; 254 | break; 255 | } 256 | default: 257 | // assuming custom user-defined type, this is the index 258 | argv[0]=JS_INT(*static_cast(value)); 259 | break; 260 | } 261 | 262 | TryCatch try_catch; 263 | 264 | Local constructorHandle = Nan::New(cb->setter); 265 | constructorHandle->Call(v8::Isolate::GetCurrent()->GetCurrentContext()->Global(), 1, argv); 266 | 267 | if (try_catch.HasCaught()) 268 | FatalException(v8::Isolate::GetCurrent(),try_catch); 269 | 270 | } 271 | 272 | void TW_CALL GetCallback(void *value, void *clientData) { 273 | // cout<<"in GetCallback"<(clientData); 277 | 278 | // build callback values 279 | Local argv[1]; 280 | argv[0]=Nan::Undefined(); 281 | 282 | TryCatch try_catch; 283 | 284 | // cout<<" calling JS getter"< ctx=Context::GetCurrent(); 286 | // Local global=ctx->Global(); 287 | // cout<<"global context: "<<*ctx<<" global object: "<<*global< fct=Nan::New(cb->getter); 289 | // Handle name=fct->GetName(); 290 | // String::Utf8Value str(name); 291 | // cout<<"getter name: "<<*str<<" callable? "<IsCallable()<<" function? "<IsFunction()<Has(name->ToString())< val=fct->Call(v8::Isolate::GetCurrent()->GetCurrentContext()->Global(), 1, argv); 295 | 296 | if (try_catch.HasCaught()) 297 | FatalException(v8::Isolate::GetCurrent(),try_catch); 298 | 299 | switch(cb->type) { 300 | case TW_TYPE_INT8: 301 | *static_cast(value) = (int8_t)val->Int32Value(); 302 | break; 303 | case TW_TYPE_UINT8: 304 | *static_cast(value) = (uint8_t)val->Uint32Value(); 305 | break; 306 | case TW_TYPE_INT16: 307 | *static_cast(value) = (int16_t)val->Int32Value(); 308 | break; 309 | case TW_TYPE_UINT16: 310 | *static_cast(value) = (uint16_t)val->Uint32Value(); 311 | break; 312 | case TW_TYPE_INT32: 313 | *static_cast(value) = (int32_t)val->Int32Value(); 314 | break; 315 | case TW_TYPE_UINT32: 316 | *static_cast(value) = (uint32_t)val->Uint32Value(); 317 | break; 318 | case TW_TYPE_FLOAT: 319 | *static_cast(value) = (float)val->NumberValue(); 320 | break; 321 | case TW_TYPE_DOUBLE: 322 | *static_cast(value) = (double)val->NumberValue(); 323 | break; 324 | case TW_TYPE_COLOR32: 325 | *static_cast(value) = (uint32_t)val->Uint32Value(); 326 | break; 327 | case TW_TYPE_COLOR3F: { 328 | Local arr=Local::Cast(val); 329 | float *zvalue=static_cast(value); 330 | zvalue[0] = (float)arr->Get(0)->NumberValue(); 331 | zvalue[1] = (float)arr->Get(1)->NumberValue(); 332 | zvalue[2] = (float)arr->Get(2)->NumberValue(); 333 | break; 334 | } 335 | case TW_TYPE_COLOR4F: { 336 | Local arr=Local::Cast(val); 337 | float *zvalue=static_cast(value); 338 | zvalue[0] = (float)arr->Get(0)->NumberValue(); 339 | zvalue[1] = (float)arr->Get(1)->NumberValue(); 340 | zvalue[2] = (float)arr->Get(2)->NumberValue(); 341 | zvalue[3] = (float)arr->Get(3)->NumberValue(); 342 | break; 343 | } 344 | case TW_TYPE_DIR3F: { 345 | Local arr=Local::Cast(val); 346 | float *zvalue=static_cast(value); 347 | zvalue[0] = (float)arr->Get(0)->NumberValue(); 348 | zvalue[1] = (float)arr->Get(1)->NumberValue(); 349 | zvalue[2] = (float)arr->Get(2)->NumberValue(); 350 | break; 351 | } 352 | case TW_TYPE_DIR3D: { 353 | Local arr=Local::Cast(val); 354 | double *zvalue=static_cast(value); 355 | zvalue[0] = (double)arr->Get(0)->NumberValue(); 356 | zvalue[1] = (double)arr->Get(1)->NumberValue(); 357 | zvalue[2] = (double)arr->Get(2)->NumberValue(); 358 | break; 359 | } 360 | case TW_TYPE_QUAT4F: { 361 | Local arr=Local::Cast(val); 362 | float *zvalue=static_cast(value); 363 | zvalue[0] = (float)arr->Get(0)->NumberValue(); 364 | zvalue[1] = (float)arr->Get(1)->NumberValue(); 365 | zvalue[2] = (float)arr->Get(2)->NumberValue(); 366 | zvalue[3] = (float)arr->Get(3)->NumberValue(); 367 | break; 368 | } 369 | case TW_TYPE_QUAT4D: { 370 | Local arr=Local::Cast(val); 371 | double *zvalue=static_cast(value); 372 | zvalue[0] = (double)arr->Get(0)->NumberValue(); 373 | zvalue[1] = (double)arr->Get(1)->NumberValue(); 374 | zvalue[2] = (double)arr->Get(2)->NumberValue(); 375 | zvalue[3] = (double)arr->Get(3)->NumberValue(); 376 | break; 377 | } 378 | default: 379 | // assuming custom user-defined type, this is the index 380 | *static_cast(value) = (uint32_t)val->Uint32Value(); 381 | break; 382 | } 383 | } 384 | 385 | void TW_CALL SetButtonCallback(void *clientData) { 386 | //cout<<"in SetButtonCallback"<(clientData); 390 | //cout<<" cb type: "<type< argv[1]; 393 | argv[0]=Nan::Undefined(); 394 | 395 | TryCatch try_catch; 396 | 397 | Local constructorHandle = Nan::New(cb->setter); 398 | constructorHandle->Call(v8::Isolate::GetCurrent()->GetCurrentContext()->Global(), 1, argv); 399 | 400 | if (try_catch.HasCaught()) 401 | FatalException(v8::Isolate::GetCurrent(),try_catch); 402 | 403 | } 404 | 405 | NAN_METHOD(Bar::AddVar) { 406 | Nan::HandleScope scope; 407 | Bar *bar = Nan::ObjectWrap::Unwrap(info.This()); 408 | String::Utf8Value name(info[0]); 409 | uint32_t type=info[1]->Uint32Value(); 410 | Local params=Local::Cast(info[2]); 411 | Local getter=Local::Cast(params->Get(JS_STR("getter"))); 412 | Local setter=Local::Cast(params->Get(JS_STR("setter"))); 413 | CB *callbacks=new CB(); 414 | bar->cbs.push_back(callbacks); 415 | callbacks->name=strdup(*name); 416 | callbacks->type=type; 417 | if(!getter->IsUndefined()) { 418 | callbacks->getter.Reset( getter); 419 | // cout<<"[AddVarRW] adding getter "<IsUndefined()) { 422 | callbacks->setter.Reset( setter); 423 | // cout<<"[AddVarRW] adding setter "< 6 | #include 7 | 8 | using namespace v8; 9 | using namespace node; 10 | 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | namespace glfw { 17 | 18 | /* @Module: GLFW initialization, termination and version querying */ 19 | 20 | NAN_METHOD(Init) { 21 | Nan::HandleScope scope; 22 | info.GetReturnValue().Set(JS_BOOL(glfwInit()==1)); 23 | } 24 | 25 | NAN_METHOD(Terminate) { 26 | Nan::HandleScope scope; 27 | glfwTerminate(); 28 | return; 29 | } 30 | 31 | NAN_METHOD(GetVersion) { 32 | Nan::HandleScope scope; 33 | int major, minor, rev; 34 | glfwGetVersion(&major,&minor,&rev); 35 | Local arr=Nan::New(3); 36 | arr->Set(JS_STR("major"),JS_INT(major)); 37 | arr->Set(JS_STR("minor"),JS_INT(minor)); 38 | arr->Set(JS_STR("rev"),JS_INT(rev)); 39 | info.GetReturnValue().Set(arr); 40 | } 41 | 42 | NAN_METHOD(GetVersionString) { 43 | Nan::HandleScope scope; 44 | const char* ver=glfwGetVersionString(); 45 | info.GetReturnValue().Set(JS_STR(ver)); 46 | } 47 | 48 | /* @Module: Time input */ 49 | 50 | NAN_METHOD(GetTime) { 51 | Nan::HandleScope scope; 52 | info.GetReturnValue().Set(JS_NUM(glfwGetTime())); 53 | } 54 | 55 | NAN_METHOD(SetTime) { 56 | Nan::HandleScope scope; 57 | double time = info[0]->NumberValue(); 58 | glfwSetTime(time); 59 | return; 60 | } 61 | 62 | /* @Module: monitor handling */ 63 | 64 | /* TODO: Monitor configuration change callback */ 65 | 66 | NAN_METHOD(GetMonitors) { 67 | Nan::HandleScope scope; 68 | int monitor_count, mode_count, xpos, ypos, width, height; 69 | int i, j; 70 | GLFWmonitor **monitors = glfwGetMonitors(&monitor_count); 71 | GLFWmonitor *primary = glfwGetPrimaryMonitor(); 72 | const GLFWvidmode *mode, *modes; 73 | 74 | Local js_monitors = Nan::New(monitor_count); 75 | Local js_monitor, js_mode; 76 | Local js_modes; 77 | for(i=0; i(); 79 | js_monitor->Set(JS_STR("is_primary"), JS_BOOL(monitors[i] == primary)); 80 | js_monitor->Set(JS_STR("index"), JS_INT(i)); 81 | 82 | js_monitor->Set(JS_STR("name"), JS_STR(glfwGetMonitorName(monitors[i]))); 83 | 84 | glfwGetMonitorPos(monitors[i], &xpos, &ypos); 85 | js_monitor->Set(JS_STR("pos_x"), JS_INT(xpos)); 86 | js_monitor->Set(JS_STR("pos_y"), JS_INT(ypos)); 87 | 88 | glfwGetMonitorPhysicalSize(monitors[i], &width, &height); 89 | js_monitor->Set(JS_STR("width_mm"), JS_INT(width)); 90 | js_monitor->Set(JS_STR("height_mm"), JS_INT(height)); 91 | 92 | mode = glfwGetVideoMode(monitors[i]); 93 | js_monitor->Set(JS_STR("width"), JS_INT(mode->width)); 94 | js_monitor->Set(JS_STR("height"), JS_INT(mode->height)); 95 | js_monitor->Set(JS_STR("rate"), JS_INT(mode->refreshRate)); 96 | 97 | modes = glfwGetVideoModes(monitors[i], &mode_count); 98 | js_modes = Nan::New(mode_count); 99 | for(j=0; j(); 101 | js_mode->Set(JS_STR("width"), JS_INT(modes[j].width)); 102 | js_mode->Set(JS_STR("height"), JS_INT(modes[j].height)); 103 | js_mode->Set(JS_STR("rate"), JS_INT(modes[j].refreshRate)); 104 | // NOTE: Are color bits necessary? 105 | js_modes->Set(JS_INT(j), js_mode); 106 | } 107 | js_monitor->Set(JS_STR("modes"), js_modes); 108 | 109 | js_monitors->Set(JS_INT(i), js_monitor); 110 | } 111 | 112 | info.GetReturnValue().Set(js_monitors); 113 | } 114 | 115 | /* @Module: Window handling */ 116 | Nan::Persistent glfw_events; 117 | int lastX=0,lastY=0; 118 | bool windowCreated=false; 119 | 120 | void NAN_INLINE(CallEmitter(int argc, Local argv[])) { 121 | Nan::HandleScope scope; 122 | // MakeCallback(glfw_events, "emit", argc, argv); 123 | if(Nan::New(glfw_events)->Has(JS_STR("emit"))) { 124 | // Local callback = Nan::New(glfw_events)->Get(JS_STR("emit")).As(); 125 | Nan::Callback callback(Nan::New(glfw_events)->Get(JS_STR("emit")).As()); 126 | 127 | if (!callback.IsEmpty()) { 128 | // callback->Call(Context::GetCurrent()->Global(),argc,argv); 129 | callback.Call(argc,argv); 130 | } 131 | } 132 | } 133 | 134 | /* Window callbacks handling */ 135 | void APIENTRY windowPosCB(GLFWwindow *window, int xpos, int ypos) { 136 | Nan::HandleScope scope; 137 | //cout<<"resizeCB: "< evt=Nan::New(3); 140 | evt->Set(JS_STR("type"),JS_STR("window_pos")); 141 | evt->Set(JS_STR("xpos"),JS_INT(xpos)); 142 | evt->Set(JS_STR("ypos"),JS_INT(ypos)); 143 | 144 | Local argv[2] = { 145 | JS_STR("window_pos"), // event name 146 | evt 147 | }; 148 | 149 | CallEmitter(2, argv); 150 | } 151 | 152 | void APIENTRY windowSizeCB(GLFWwindow *window, int w, int h) { 153 | Nan::HandleScope scope; 154 | //cout<<"resizeCB: "< evt=Nan::New(3); 157 | evt->Set(JS_STR("type"),JS_STR("resize")); 158 | evt->Set(JS_STR("width"),JS_INT(w)); 159 | evt->Set(JS_STR("height"),JS_INT(h)); 160 | 161 | Local argv[2] = { 162 | JS_STR("resize"), // event name 163 | evt 164 | }; 165 | 166 | CallEmitter(2, argv); 167 | } 168 | 169 | void APIENTRY windowFramebufferSizeCB(GLFWwindow *window, int w, int h) { 170 | Nan::HandleScope scope; 171 | //cout<<"resizeCB: "< evt=Nan::New(3); 174 | evt->Set(JS_STR("type"),JS_STR("framebuffer_resize")); 175 | evt->Set(JS_STR("width"),JS_INT(w)); 176 | evt->Set(JS_STR("height"),JS_INT(h)); 177 | 178 | Local argv[2] = { 179 | JS_STR("framebuffer_resize"), // event name 180 | evt 181 | }; 182 | 183 | CallEmitter(2, argv); 184 | } 185 | 186 | void APIENTRY windowCloseCB(GLFWwindow *window) { 187 | Nan::HandleScope scope; 188 | 189 | Local argv[1] = { 190 | JS_STR("quit"), // event name 191 | }; 192 | 193 | CallEmitter(1, argv); 194 | } 195 | 196 | void APIENTRY windowRefreshCB(GLFWwindow *window) { 197 | Nan::HandleScope scope; 198 | 199 | Local evt=Nan::New(2); 200 | evt->Set(JS_STR("type"),JS_STR("refresh")); 201 | evt->Set(JS_STR("window"),JS_NUM((uint64_t) window)); 202 | 203 | Local argv[2] = { 204 | JS_STR("refresh"), // event name 205 | evt 206 | }; 207 | 208 | CallEmitter(2, argv); 209 | } 210 | 211 | void APIENTRY windowIconifyCB(GLFWwindow *window, int iconified) { 212 | Nan::HandleScope scope; 213 | 214 | Local evt=Nan::New(2); 215 | evt->Set(JS_STR("type"),JS_STR("iconified")); 216 | evt->Set(JS_STR("iconified"),JS_BOOL(iconified)); 217 | 218 | Local argv[2] = { 219 | JS_STR("iconified"), // event name 220 | evt 221 | }; 222 | 223 | CallEmitter(2, argv); 224 | } 225 | 226 | void APIENTRY windowFocusCB(GLFWwindow *window, int focused) { 227 | Nan::HandleScope scope; 228 | 229 | Local evt=Nan::New(2); 230 | evt->Set(JS_STR("type"),JS_STR("focused")); 231 | evt->Set(JS_STR("focused"),JS_BOOL(focused)); 232 | 233 | Local argv[2] = { 234 | JS_STR("focused"), // event name 235 | evt 236 | }; 237 | 238 | CallEmitter(2, argv); 239 | } 240 | 241 | static int jsKeyCode[]={ 242 | /*GLFW_KEY_ESCAPE*/ 27, 243 | /*GLFW_KEY_ENTER*/ 13, 244 | /*GLFW_KEY_TAB*/ 9, 245 | /*GLFW_KEY_BACKSPACE*/ 8, 246 | /*GLFW_KEY_INSERT*/ 45, 247 | /*GLFW_KEY_DELETE*/ 46, 248 | /*GLFW_KEY_RIGHT*/ 39, 249 | /*GLFW_KEY_LEFT*/ 37, 250 | /*GLFW_KEY_DOWN*/ 40, 251 | /*GLFW_KEY_UP*/ 38, 252 | /*GLFW_KEY_PAGE_UP*/ 33, 253 | /*GLFW_KEY_PAGE_DOWN*/ 34, 254 | /*GLFW_KEY_HOME*/ 36, 255 | /*GLFW_KEY_END*/ 35, 256 | /*GLFW_KEY_CAPS_LOCK*/ 20, 257 | /*GLFW_KEY_SCROLL_LOCK*/ 145, 258 | /*GLFW_KEY_NUM_LOCK*/ 144, 259 | /*GLFW_KEY_PRINT_SCREEN*/ 144, /* TODO */ 260 | /*GLFW_KEY_PAUSE*/ 19, 261 | /*GLFW_KEY_F1*/ 112, 262 | /*GLFW_KEY_F2*/ 113, 263 | /*GLFW_KEY_F3*/ 114, 264 | /*GLFW_KEY_F4*/ 115, 265 | /*GLFW_KEY_F5*/ 116, 266 | /*GLFW_KEY_F6*/ 117, 267 | /*GLFW_KEY_F7*/ 118, 268 | /*GLFW_KEY_F8*/ 119, 269 | /*GLFW_KEY_F9*/ 120, 270 | /*GLFW_KEY_F10*/ 121, 271 | /*GLFW_KEY_F11*/ 122, 272 | /*GLFW_KEY_F12*/ 123, 273 | /*GLFW_KEY_F13*/ 123, /* unknown */ 274 | /*GLFW_KEY_F14*/ 123, /* unknown */ 275 | /*GLFW_KEY_F15*/ 123, /* unknown */ 276 | /*GLFW_KEY_F16*/ 123, /* unknown */ 277 | /*GLFW_KEY_F17*/ 123, /* unknown */ 278 | /*GLFW_KEY_F18*/ 123, /* unknown */ 279 | /*GLFW_KEY_F19*/ 123, /* unknown */ 280 | /*GLFW_KEY_F20*/ 123, /* unknown */ 281 | /*GLFW_KEY_F21*/ 123, /* unknown */ 282 | /*GLFW_KEY_F22*/ 123, /* unknown */ 283 | /*GLFW_KEY_F23*/ 123, /* unknown */ 284 | /*GLFW_KEY_F24*/ 123, /* unknown */ 285 | /*GLFW_KEY_F25*/ 123, /* unknown */ 286 | /*GLFW_KEY_KP_0*/ 96, 287 | /*GLFW_KEY_KP_1*/ 97, 288 | /*GLFW_KEY_KP_2*/ 98, 289 | /*GLFW_KEY_KP_3*/ 99, 290 | /*GLFW_KEY_KP_4*/ 100, 291 | /*GLFW_KEY_KP_5*/ 101, 292 | /*GLFW_KEY_KP_6*/ 102, 293 | /*GLFW_KEY_KP_7*/ 103, 294 | /*GLFW_KEY_KP_8*/ 104, 295 | /*GLFW_KEY_KP_9*/ 105, 296 | /*GLFW_KEY_KP_DECIMAL*/ 110, 297 | /*GLFW_KEY_KP_DIVIDE*/ 111, 298 | /*GLFW_KEY_KP_MULTIPLY*/ 106, 299 | /*GLFW_KEY_KP_SUBTRACT*/ 109, 300 | /*GLFW_KEY_KP_ADD*/ 107, 301 | /*GLFW_KEY_KP_ENTER*/ 13, 302 | /*GLFW_KEY_KP_EQUAL*/ 187, 303 | /*GLFW_KEY_LEFT_SHIFT*/ 16, 304 | /*GLFW_KEY_LEFT_CONTROL*/ 17, 305 | /*GLFW_KEY_LEFT_ALT*/ 18, 306 | /*GLFW_KEY_LEFT_SUPER*/ 91, 307 | /*GLFW_KEY_RIGHT_SHIFT*/ 16, 308 | /*GLFW_KEY_RIGHT_CONTROL*/17, 309 | /*GLFW_KEY_RIGHT_ALT*/ 18, 310 | /*GLFW_KEY_RIGHT_SUPER*/ 93, 311 | /*GLFW_KEY_MENU*/ 18 312 | }; 313 | 314 | void APIENTRY keyCB(GLFWwindow *window, int key, int scancode, int action, int mods) { 315 | const char *actionNames = "keyup\0 keydown\0keypress"; 316 | 317 | if(!TwEventKeyGLFW(key,action)) { 318 | Nan::HandleScope scope; 319 | 320 | Local evt=Nan::New(7); 321 | evt->Set(JS_STR("type"), JS_STR( &actionNames[action << 3] )); 322 | evt->Set(JS_STR("ctrlKey"),JS_BOOL(mods & GLFW_MOD_CONTROL)); 323 | evt->Set(JS_STR("shiftKey"),JS_BOOL(mods & GLFW_MOD_SHIFT)); 324 | evt->Set(JS_STR("altKey"),JS_BOOL(mods & GLFW_MOD_ALT)); 325 | evt->Set(JS_STR("metaKey"),JS_BOOL(mods & GLFW_MOD_SUPER)); 326 | 327 | int which=key, charCode=key; 328 | 329 | if(key>=GLFW_KEY_ESCAPE && key<=GLFW_KEY_LAST) 330 | key=jsKeyCode[key-GLFW_KEY_ESCAPE]; 331 | else if(key==GLFW_KEY_SEMICOLON) key=186; // ; 332 | else if(key==GLFW_KEY_EQUAL) key=187; // = 333 | else if(key==GLFW_KEY_COMMA) key=188; // , 334 | else if(key==GLFW_KEY_MINUS) key=189; // - 335 | else if(key==GLFW_KEY_PERIOD) key=190; // . 336 | else if(key==GLFW_KEY_SLASH) key=191; // / 337 | else if(key==GLFW_KEY_GRAVE_ACCENT) key=192; // ` 338 | else if(key==GLFW_KEY_LEFT_BRACKET) key=219; // [ 339 | else if(key==GLFW_KEY_BACKSLASH) key=220; /* \ */ 340 | else if(key==GLFW_KEY_RIGHT_BRACKET) key=221;// ] 341 | else if(key==GLFW_KEY_APOSTROPHE) key=222; // ' 342 | 343 | evt->Set(JS_STR("which"),JS_INT(which)); 344 | evt->Set(JS_STR("keyCode"),JS_INT(key)); 345 | evt->Set(JS_STR("charCode"),JS_INT(charCode)); 346 | 347 | Local argv[2] = { 348 | JS_STR(&actionNames[action << 3]), // event name 349 | evt 350 | }; 351 | 352 | CallEmitter(2, argv); 353 | } 354 | } 355 | 356 | void APIENTRY cursorPosCB(GLFWwindow* window, double x, double y) { 357 | if(!TwEventMousePosGLFW(x,y)) { 358 | int w,h; 359 | glfwGetWindowSize(window, &w, &h); 360 | if(x<0 || x>=w) return; 361 | if(y<0 || y>=h) return; 362 | 363 | lastX=x; 364 | lastY=y; 365 | 366 | Nan::HandleScope scope; 367 | 368 | Local evt=Nan::New(5); 369 | evt->Set(JS_STR("type"),JS_STR("mousemove")); 370 | evt->Set(JS_STR("pageX"),JS_NUM(x)); 371 | evt->Set(JS_STR("pageY"),JS_NUM(y)); 372 | evt->Set(JS_STR("x"),JS_NUM(x)); 373 | evt->Set(JS_STR("y"),JS_NUM(y)); 374 | 375 | Local argv[2] = { 376 | JS_STR("mousemove"), // event name 377 | evt 378 | }; 379 | 380 | CallEmitter(2, argv); 381 | } 382 | } 383 | 384 | void APIENTRY cursorEnterCB(GLFWwindow* window, int entered) { 385 | Nan::HandleScope scope; 386 | 387 | Local evt=Nan::New(2); 388 | evt->Set(JS_STR("type"),JS_STR("mouseenter")); 389 | evt->Set(JS_STR("entered"),JS_INT(entered)); 390 | 391 | Local argv[2] = { 392 | JS_STR("mouseenter"), // event name 393 | evt 394 | }; 395 | 396 | CallEmitter(2, argv); 397 | } 398 | 399 | void APIENTRY mouseButtonCB(GLFWwindow *window, int button, int action, int mods) { 400 | if(!TwEventMouseButtonGLFW(button,action)) { 401 | Nan::HandleScope scope; 402 | Local evt=Nan::New(7); 403 | evt->Set(JS_STR("type"),JS_STR(action ? "mousedown" : "mouseup")); 404 | evt->Set(JS_STR("button"),JS_INT(button)); 405 | evt->Set(JS_STR("which"),JS_INT(button)); 406 | evt->Set(JS_STR("x"),JS_INT(lastX)); 407 | evt->Set(JS_STR("y"),JS_INT(lastY)); 408 | evt->Set(JS_STR("pageX"),JS_INT(lastX)); 409 | evt->Set(JS_STR("pageY"),JS_INT(lastY)); 410 | 411 | Local argv[2] = { 412 | JS_STR(action ? "mousedown" : "mouseup"), // event name 413 | evt 414 | }; 415 | 416 | CallEmitter(2, argv); 417 | } 418 | } 419 | 420 | void APIENTRY scrollCB(GLFWwindow *window, double xoffset, double yoffset) { 421 | if(!TwEventMouseWheelGLFW(yoffset)) { 422 | Nan::HandleScope scope; 423 | 424 | Local evt=Nan::New(3); 425 | evt->Set(JS_STR("type"),JS_STR("mousewheel")); 426 | evt->Set(JS_STR("wheelDeltaX"),JS_NUM(xoffset*120)); 427 | evt->Set(JS_STR("wheelDeltaY"),JS_NUM(yoffset*120)); 428 | evt->Set(JS_STR("wheelDelta"),JS_NUM(yoffset*120)); 429 | 430 | Local argv[2] = { 431 | JS_STR("mousewheel"), // event name 432 | evt 433 | }; 434 | 435 | CallEmitter(2, argv); 436 | } 437 | } 438 | 439 | int APIENTRY windowCloseCB() { 440 | Nan::HandleScope scope; 441 | 442 | Local argv[1] = { 443 | JS_STR("quit"), // event name 444 | }; 445 | 446 | CallEmitter(1, argv); 447 | 448 | return 1; 449 | } 450 | 451 | NAN_METHOD(testJoystick) { 452 | Nan::HandleScope scope; 453 | 454 | int width = info[0]->Uint32Value(); 455 | int height = info[1]->Uint32Value(); 456 | float ratio = width / (float) height; 457 | 458 | float translateX = info[2]->NumberValue(); 459 | float translateY = info[3]->NumberValue(); 460 | float translateZ = info[4]->NumberValue(); 461 | 462 | float rotateX = info[5]->NumberValue(); 463 | float rotateY = info[6]->NumberValue(); 464 | float rotateZ = info[7]->NumberValue(); 465 | 466 | float angle = info[8]->NumberValue(); 467 | 468 | glViewport(0, 0, width, height); 469 | glClear(GL_COLOR_BUFFER_BIT); 470 | 471 | glMatrixMode(GL_PROJECTION); 472 | glLoadIdentity(); 473 | glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f); 474 | glMatrixMode(GL_MODELVIEW); 475 | 476 | glLoadIdentity(); 477 | glRotatef(angle, rotateX, rotateY, rotateZ); 478 | glTranslatef(translateX, translateY, translateZ); 479 | 480 | glBegin(GL_TRIANGLES); 481 | glColor3f(1.f, 0.f, 0.f); 482 | glVertex3f(-0.6f, -0.4f, 0.f); 483 | glColor3f(0.f, 1.f, 0.f); 484 | glVertex3f(0.6f, -0.4f, 0.f); 485 | glColor3f(0.f, 0.f, 1.f); 486 | glVertex3f(0.f, 0.6f, 0.f); 487 | glEnd(); 488 | 489 | return; 490 | } 491 | 492 | NAN_METHOD(testScene) { 493 | Nan::HandleScope scope; 494 | int width = info[0]->Uint32Value(); 495 | int height = info[1]->Uint32Value(); 496 | float z = info.Length()>2 ? (float) info[2]->NumberValue() : 0; 497 | float ratio = width / (float) height; 498 | 499 | glViewport(0, 0, width, height); 500 | glClear(GL_COLOR_BUFFER_BIT); 501 | 502 | glMatrixMode(GL_PROJECTION); 503 | glLoadIdentity(); 504 | glOrtho(-ratio, ratio, -1.f, 1.f, 1.f, -1.f); 505 | glMatrixMode(GL_MODELVIEW); 506 | 507 | glLoadIdentity(); 508 | glRotatef((float) glfwGetTime() * 50.f, 0.f, 0.f, 1.f); 509 | 510 | glBegin(GL_TRIANGLES); 511 | glColor3f(1.f, 0.f, 0.f); 512 | glVertex3f(-0.6f+z, -0.4f, 0.f); 513 | glColor3f(0.f, 1.f, 0.f); 514 | glVertex3f(0.6f+z, -0.4f, 0.f); 515 | glColor3f(0.f, 0.f, 1.f); 516 | glVertex3f(0.f+z, 0.6f, 0.f); 517 | glEnd(); 518 | 519 | return; 520 | } 521 | 522 | NAN_METHOD(WindowHint) { 523 | Nan::HandleScope scope; 524 | int target = info[0]->Uint32Value(); 525 | int hint = info[1]->Uint32Value(); 526 | glfwWindowHint(target, hint); 527 | return; 528 | } 529 | 530 | NAN_METHOD(DefaultWindowHints) { 531 | Nan::HandleScope scope; 532 | glfwDefaultWindowHints(); 533 | return; 534 | } 535 | 536 | NAN_METHOD(JoystickPresent) { 537 | Nan::HandleScope scope; 538 | int joy = info[0]->Uint32Value(); 539 | bool isPresent = glfwJoystickPresent(joy); 540 | info.GetReturnValue().Set(JS_BOOL(isPresent)); 541 | } 542 | 543 | std::string intToString(int number) { 544 | std::ostringstream buff; 545 | buff << number; 546 | return buff.str(); 547 | } 548 | 549 | std::string floatToString(float number){ 550 | std::ostringstream buff; 551 | buff<Uint32Value(); 563 | int count; 564 | const float *axisValues = glfwGetJoystickAxes(joy, &count); 565 | string response = ""; 566 | for (int i = 0; i < count; i++) { 567 | response.append(floatToString(axisValues[i])); 568 | response.append(","); //Separator 569 | } 570 | 571 | info.GetReturnValue().Set(JS_STR(response.c_str())); 572 | } 573 | 574 | NAN_METHOD(GetJoystickButtons) { 575 | Nan::HandleScope scope; 576 | int joy = info[0]->Uint32Value(); 577 | int count = 0; 578 | const unsigned char* response = glfwGetJoystickButtons(joy, &count); 579 | 580 | string strResponse = ""; 581 | for (int i = 0; i < count; i++) { 582 | strResponse.append(buttonToString(response[i])); 583 | strResponse.append(","); 584 | } 585 | 586 | info.GetReturnValue().Set(JS_STR(strResponse.c_str())); 587 | } 588 | 589 | NAN_METHOD(GetJoystickName) { 590 | Nan::HandleScope scope; 591 | int joy = info[0]->Uint32Value(); 592 | const char* response = glfwGetJoystickName(joy); 593 | info.GetReturnValue().Set(JS_STR(response)); 594 | } 595 | 596 | NAN_METHOD(glfw_CreateWindow) { 597 | Nan::HandleScope scope; 598 | int width = info[0]->Uint32Value(); 599 | int height = info[1]->Uint32Value(); 600 | String::Utf8Value str(info[2]->ToString()); 601 | int monitor_idx = info[3]->Uint32Value(); 602 | 603 | GLFWwindow* window = NULL; 604 | GLFWmonitor **monitors = NULL, *monitor = NULL; 605 | int monitor_count; 606 | if(info.Length() >= 4 && monitor_idx >= 0){ 607 | monitors = glfwGetMonitors(&monitor_count); 608 | if(monitor_idx >= monitor_count){ 609 | return Nan::ThrowError("Invalid monitor"); 610 | } 611 | monitor = monitors[monitor_idx]; 612 | } 613 | 614 | if(!windowCreated) { 615 | window = glfwCreateWindow(width, height, *str, monitor, NULL); 616 | 617 | if(!window) { 618 | // can't create window, throw error 619 | return Nan::ThrowError("Can't create GLFW window"); 620 | } 621 | 622 | glfwMakeContextCurrent(window); 623 | 624 | // make sure cursor is always shown 625 | glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_NORMAL); 626 | 627 | GLenum err = glewInit(); 628 | if (err) 629 | { 630 | /* Problem: glewInit failed, something is seriously wrong. */ 631 | string msg="Can't init GLEW (glew error "; 632 | msg+=(const char*) glewGetErrorString(err); 633 | msg+=")"; 634 | 635 | fprintf(stderr, "%s", msg.c_str()); 636 | return Nan::ThrowError(msg.c_str()); 637 | } 638 | fprintf(stdout, "Status: Using GLEW %s\n", glewGetString(GLEW_VERSION)); 639 | } 640 | else 641 | glfwSetWindowSize(window, width,height); 642 | 643 | // Set callback functions 644 | glfw_events.Reset( info.This()->Get(JS_STR("events"))->ToObject()); 645 | 646 | // window callbacks 647 | glfwSetWindowPosCallback( window, windowPosCB ); 648 | glfwSetWindowSizeCallback( window, windowSizeCB ); 649 | glfwSetWindowCloseCallback( window, windowCloseCB ); 650 | glfwSetWindowRefreshCallback( window, windowRefreshCB ); 651 | glfwSetWindowFocusCallback( window, windowFocusCB ); 652 | glfwSetWindowIconifyCallback( window, windowIconifyCB ); 653 | glfwSetFramebufferSizeCallback( window, windowFramebufferSizeCB ); 654 | 655 | // input callbacks 656 | glfwSetKeyCallback( window, keyCB); 657 | // TODO glfwSetCharCallback(window, TwEventCharGLFW); 658 | glfwSetMouseButtonCallback( window, mouseButtonCB ); 659 | glfwSetCursorPosCallback( window, cursorPosCB ); 660 | glfwSetCursorEnterCallback( window, cursorEnterCB ); 661 | glfwSetScrollCallback( window, scrollCB ); 662 | 663 | info.GetReturnValue().Set(JS_NUM((uint64_t) window)); 664 | } 665 | 666 | NAN_METHOD(DestroyWindow) { 667 | Nan::HandleScope scope; 668 | uint64_t handle=info[0]->IntegerValue(); 669 | if(handle) { 670 | GLFWwindow* window = reinterpret_cast(handle); 671 | glfwDestroyWindow(window); 672 | } 673 | return; 674 | } 675 | 676 | NAN_METHOD(SetWindowTitle) { 677 | Nan::HandleScope scope; 678 | uint64_t handle=info[0]->IntegerValue(); 679 | String::Utf8Value str(info[1]->ToString()); 680 | if(handle) { 681 | GLFWwindow* window = reinterpret_cast(handle); 682 | glfwSetWindowTitle(window, *str); 683 | } 684 | return; 685 | } 686 | 687 | NAN_METHOD(GetWindowSize) { 688 | Nan::HandleScope scope; 689 | uint64_t handle=info[0]->IntegerValue(); 690 | if(handle) { 691 | int w,h; 692 | GLFWwindow* window = reinterpret_cast(handle); 693 | glfwGetWindowSize(window, &w, &h); 694 | Local arr=Nan::New(2); 695 | arr->Set(JS_STR("width"),JS_INT(w)); 696 | arr->Set(JS_STR("height"),JS_INT(h)); 697 | info.GetReturnValue().Set(arr); 698 | } 699 | return; 700 | } 701 | 702 | NAN_METHOD(SetWindowSize) { 703 | Nan::HandleScope scope; 704 | uint64_t handle=info[0]->IntegerValue(); 705 | if(handle) { 706 | GLFWwindow* window = reinterpret_cast(handle); 707 | glfwSetWindowSize(window, info[1]->Uint32Value(),info[2]->Uint32Value()); 708 | } 709 | return; 710 | } 711 | 712 | NAN_METHOD(SetWindowPos) { 713 | Nan::HandleScope scope; 714 | uint64_t handle=info[0]->IntegerValue(); 715 | if(handle) { 716 | GLFWwindow* window = reinterpret_cast(handle); 717 | glfwSetWindowPos(window, info[1]->Uint32Value(),info[2]->Uint32Value()); 718 | } 719 | return; 720 | } 721 | 722 | NAN_METHOD(GetWindowPos) { 723 | Nan::HandleScope scope; 724 | uint64_t handle=info[0]->IntegerValue(); 725 | if(handle) { 726 | GLFWwindow* window = reinterpret_cast(handle); 727 | int xpos, ypos; 728 | glfwGetWindowPos(window, &xpos, &ypos); 729 | Local arr=Nan::New(2); 730 | arr->Set(JS_STR("xpos"),JS_INT(xpos)); 731 | arr->Set(JS_STR("ypos"),JS_INT(ypos)); 732 | info.GetReturnValue().Set(arr); 733 | } 734 | return; 735 | } 736 | 737 | NAN_METHOD(GetFramebufferSize) { 738 | Nan::HandleScope scope; 739 | uint64_t handle=info[0]->IntegerValue(); 740 | if(handle) { 741 | GLFWwindow* window = reinterpret_cast(handle); 742 | int width, height; 743 | glfwGetFramebufferSize(window, &width, &height); 744 | Local arr=Nan::New(2); 745 | arr->Set(JS_STR("width"),JS_INT(width)); 746 | arr->Set(JS_STR("height"),JS_INT(height)); 747 | info.GetReturnValue().Set(arr); 748 | } 749 | return; 750 | } 751 | 752 | NAN_METHOD(IconifyWindow) { 753 | Nan::HandleScope scope; 754 | uint64_t handle=info[0]->IntegerValue(); 755 | if(handle) { 756 | GLFWwindow* window = reinterpret_cast(handle); 757 | glfwIconifyWindow(window); 758 | } 759 | return; 760 | } 761 | 762 | NAN_METHOD(RestoreWindow) { 763 | Nan::HandleScope scope; 764 | uint64_t handle=info[0]->IntegerValue(); 765 | if(handle) { 766 | GLFWwindow* window = reinterpret_cast(handle); 767 | glfwRestoreWindow(window); 768 | } 769 | return; 770 | } 771 | 772 | NAN_METHOD(HideWindow) { 773 | Nan::HandleScope scope; 774 | uint64_t handle=info[0]->IntegerValue(); 775 | if(handle) { 776 | GLFWwindow* window = reinterpret_cast(handle); 777 | glfwHideWindow(window); 778 | } 779 | return; 780 | } 781 | 782 | NAN_METHOD(ShowWindow) { 783 | Nan::HandleScope scope; 784 | uint64_t handle=info[0]->IntegerValue(); 785 | if(handle) { 786 | GLFWwindow* window = reinterpret_cast(handle); 787 | glfwShowWindow(window); 788 | } 789 | return; 790 | } 791 | 792 | NAN_METHOD(WindowShouldClose) { 793 | Nan::HandleScope scope; 794 | uint64_t handle=info[0]->IntegerValue(); 795 | if(handle) { 796 | GLFWwindow* window = reinterpret_cast(handle); 797 | info.GetReturnValue().Set(JS_INT(glfwWindowShouldClose(window))); 798 | } 799 | return; 800 | } 801 | 802 | NAN_METHOD(SetWindowShouldClose) { 803 | Nan::HandleScope scope; 804 | uint64_t handle=info[0]->IntegerValue(); 805 | int value=info[1]->Uint32Value(); 806 | if(handle) { 807 | GLFWwindow* window = reinterpret_cast(handle); 808 | glfwSetWindowShouldClose(window, value); 809 | } 810 | return; 811 | } 812 | 813 | NAN_METHOD(GetWindowAttrib) { 814 | Nan::HandleScope scope; 815 | uint64_t handle=info[0]->IntegerValue(); 816 | int attrib=info[1]->Uint32Value(); 817 | if(handle) { 818 | GLFWwindow* window = reinterpret_cast(handle); 819 | info.GetReturnValue().Set(JS_INT(glfwGetWindowAttrib(window, attrib))); 820 | } 821 | return; 822 | } 823 | 824 | NAN_METHOD(PollEvents) { 825 | Nan::HandleScope scope; 826 | glfwPollEvents(); 827 | return; 828 | } 829 | 830 | NAN_METHOD(WaitEvents) { 831 | Nan::HandleScope scope; 832 | glfwWaitEvents(); 833 | return; 834 | } 835 | 836 | /* Input handling */ 837 | NAN_METHOD(GetKey) { 838 | Nan::HandleScope scope; 839 | uint64_t handle=info[0]->IntegerValue(); 840 | int key=info[1]->Uint32Value(); 841 | if(handle) { 842 | GLFWwindow* window = reinterpret_cast(handle); 843 | info.GetReturnValue().Set(JS_INT(glfwGetKey(window, key))); 844 | } 845 | return; 846 | } 847 | 848 | NAN_METHOD(GetMouseButton) { 849 | Nan::HandleScope scope; 850 | uint64_t handle=info[0]->IntegerValue(); 851 | int button=info[1]->Uint32Value(); 852 | if(handle) { 853 | GLFWwindow* window = reinterpret_cast(handle); 854 | info.GetReturnValue().Set(JS_INT(glfwGetMouseButton(window, button))); 855 | } 856 | return; 857 | } 858 | 859 | NAN_METHOD(GetCursorPos) { 860 | Nan::HandleScope scope; 861 | uint64_t handle=info[0]->IntegerValue(); 862 | if(handle) { 863 | GLFWwindow* window = reinterpret_cast(handle); 864 | double x,y; 865 | glfwGetCursorPos(window, &x, &y); 866 | Local arr=Nan::New(2); 867 | arr->Set(JS_STR("x"),JS_NUM(x)); 868 | arr->Set(JS_STR("y"),JS_NUM(y)); 869 | info.GetReturnValue().Set(arr); 870 | } 871 | return; 872 | } 873 | 874 | NAN_METHOD(SetCursorPos) { 875 | Nan::HandleScope scope; 876 | uint64_t handle=info[0]->IntegerValue(); 877 | int x=info[1]->NumberValue(); 878 | int y=info[2]->NumberValue(); 879 | if(handle) { 880 | GLFWwindow* window = reinterpret_cast(handle); 881 | glfwSetCursorPos(window, x, y); 882 | } 883 | return; 884 | } 885 | 886 | /* @Module Context handling */ 887 | NAN_METHOD(MakeContextCurrent) { 888 | Nan::HandleScope scope; 889 | uint64_t handle=info[0]->IntegerValue(); 890 | if(handle) { 891 | GLFWwindow* window = reinterpret_cast(handle); 892 | glfwMakeContextCurrent(window); 893 | } 894 | return; 895 | } 896 | 897 | NAN_METHOD(GetCurrentContext) { 898 | Nan::HandleScope scope; 899 | GLFWwindow* window=glfwGetCurrentContext(); 900 | info.GetReturnValue().Set(JS_NUM((uint64_t) window)); 901 | } 902 | 903 | NAN_METHOD(SwapBuffers) { 904 | Nan::HandleScope scope; 905 | uint64_t handle=info[0]->IntegerValue(); 906 | if(handle) { 907 | GLFWwindow* window = reinterpret_cast(handle); 908 | glfwSwapBuffers(window); 909 | } 910 | return; 911 | } 912 | 913 | NAN_METHOD(SwapInterval) { 914 | Nan::HandleScope scope; 915 | int interval=info[0]->Int32Value(); 916 | glfwSwapInterval(interval); 917 | return; 918 | } 919 | 920 | /* Extension support */ 921 | NAN_METHOD(ExtensionSupported) { 922 | Nan::HandleScope scope; 923 | String::Utf8Value str(info[0]->ToString()); 924 | info.GetReturnValue().Set(JS_BOOL(glfwExtensionSupported(*str)==1)); 925 | } 926 | 927 | // make sure we close everything when we exit 928 | void AtExit() { 929 | TwTerminate(); 930 | glfwTerminate(); 931 | } 932 | 933 | } // namespace glfw 934 | 935 | /////////////////////////////////////////////////////////////////////////////// 936 | // 937 | // bindings 938 | // 939 | /////////////////////////////////////////////////////////////////////////////// 940 | #define JS_GLFW_CONSTANT(name) target->Set(JS_STR( #name ), JS_INT(GLFW_ ## name)) 941 | #define JS_GLFW_SET_METHOD(name) Nan::SetMethod(target, #name , glfw::name); 942 | 943 | extern "C" { 944 | NAN_MODULE_INIT(init) 945 | { 946 | atexit(glfw::AtExit); 947 | 948 | Nan::HandleScope scope; 949 | 950 | /* GLFW initialization, termination and version querying */ 951 | JS_GLFW_SET_METHOD(Init); 952 | JS_GLFW_SET_METHOD(Terminate); 953 | JS_GLFW_SET_METHOD(GetVersion); 954 | JS_GLFW_SET_METHOD(GetVersionString); 955 | 956 | /* Time */ 957 | JS_GLFW_SET_METHOD(GetTime); 958 | JS_GLFW_SET_METHOD(SetTime); 959 | 960 | /* Monitor handling */ 961 | JS_GLFW_SET_METHOD(GetMonitors); 962 | 963 | /* Window handling */ 964 | //JS_GLFW_SET_METHOD(CreateWindow); 965 | Nan::SetMethod(target, "CreateWindow", glfw::glfw_CreateWindow); 966 | JS_GLFW_SET_METHOD(WindowHint); 967 | JS_GLFW_SET_METHOD(DefaultWindowHints); 968 | JS_GLFW_SET_METHOD(DestroyWindow); 969 | JS_GLFW_SET_METHOD(SetWindowShouldClose); 970 | JS_GLFW_SET_METHOD(WindowShouldClose); 971 | JS_GLFW_SET_METHOD(SetWindowTitle); 972 | JS_GLFW_SET_METHOD(GetWindowSize); 973 | JS_GLFW_SET_METHOD(SetWindowSize); 974 | JS_GLFW_SET_METHOD(SetWindowPos); 975 | JS_GLFW_SET_METHOD(GetWindowPos); 976 | JS_GLFW_SET_METHOD(GetFramebufferSize); 977 | JS_GLFW_SET_METHOD(IconifyWindow); 978 | JS_GLFW_SET_METHOD(RestoreWindow); 979 | JS_GLFW_SET_METHOD(ShowWindow); 980 | JS_GLFW_SET_METHOD(HideWindow); 981 | JS_GLFW_SET_METHOD(GetWindowAttrib); 982 | JS_GLFW_SET_METHOD(PollEvents); 983 | JS_GLFW_SET_METHOD(WaitEvents); 984 | 985 | /* Input handling */ 986 | JS_GLFW_SET_METHOD(GetKey); 987 | JS_GLFW_SET_METHOD(GetMouseButton); 988 | JS_GLFW_SET_METHOD(GetCursorPos); 989 | JS_GLFW_SET_METHOD(SetCursorPos); 990 | 991 | /* Context handling */ 992 | JS_GLFW_SET_METHOD(MakeContextCurrent); 993 | JS_GLFW_SET_METHOD(GetCurrentContext); 994 | JS_GLFW_SET_METHOD(SwapBuffers); 995 | JS_GLFW_SET_METHOD(SwapInterval); 996 | JS_GLFW_SET_METHOD(ExtensionSupported); 997 | 998 | /* Joystick */ 999 | JS_GLFW_SET_METHOD(JoystickPresent); 1000 | JS_GLFW_SET_METHOD(GetJoystickAxes); 1001 | JS_GLFW_SET_METHOD(GetJoystickButtons); 1002 | JS_GLFW_SET_METHOD(GetJoystickName); 1003 | 1004 | /************************************************************************* 1005 | * GLFW version 1006 | *************************************************************************/ 1007 | 1008 | JS_GLFW_CONSTANT(VERSION_MAJOR); 1009 | JS_GLFW_CONSTANT(VERSION_MINOR); 1010 | JS_GLFW_CONSTANT(VERSION_REVISION); 1011 | 1012 | /************************************************************************* 1013 | * Input handling definitions 1014 | *************************************************************************/ 1015 | 1016 | /* Key and button state/action definitions */ 1017 | JS_GLFW_CONSTANT(RELEASE); 1018 | JS_GLFW_CONSTANT(PRESS); 1019 | JS_GLFW_CONSTANT(REPEAT); 1020 | 1021 | /* These key codes are inspired by the *USB HID Usage Tables v1.12* (p. 53-60), 1022 | * but re-arranged to map to 7-bit ASCII for printable keys (function keys are 1023 | * put in the 256+ range). 1024 | * 1025 | * The naming of the key codes follow these rules: 1026 | * - The US keyboard layout is used 1027 | * - Names of printable alpha-numeric characters are used (e.g. "A", "R", 1028 | * "3", etc.) 1029 | * - For non-alphanumeric characters, Unicode:ish names are used (e.g. 1030 | * "COMMA", "LEFT_SQUARE_BRACKET", etc.). Note that some names do not 1031 | * correspond to the Unicode standard (usually for brevity) 1032 | * - Keys that lack a clear US mapping are named "WORLD_x" 1033 | * - For non-printable keys, custom names are used (e.g. "F4", 1034 | * "BACKSPACE", etc.) 1035 | */ 1036 | 1037 | /* The unknown key */ 1038 | JS_GLFW_CONSTANT(KEY_UNKNOWN); 1039 | 1040 | /* Printable keys */ 1041 | JS_GLFW_CONSTANT(KEY_SPACE); 1042 | JS_GLFW_CONSTANT(KEY_APOSTROPHE); 1043 | JS_GLFW_CONSTANT(KEY_COMMA); 1044 | JS_GLFW_CONSTANT(KEY_MINUS); 1045 | JS_GLFW_CONSTANT(KEY_PERIOD); 1046 | JS_GLFW_CONSTANT(KEY_SLASH); 1047 | JS_GLFW_CONSTANT(KEY_0); 1048 | JS_GLFW_CONSTANT(KEY_1); 1049 | JS_GLFW_CONSTANT(KEY_2); 1050 | JS_GLFW_CONSTANT(KEY_3); 1051 | JS_GLFW_CONSTANT(KEY_4); 1052 | JS_GLFW_CONSTANT(KEY_5); 1053 | JS_GLFW_CONSTANT(KEY_6); 1054 | JS_GLFW_CONSTANT(KEY_7); 1055 | JS_GLFW_CONSTANT(KEY_8); 1056 | JS_GLFW_CONSTANT(KEY_9); 1057 | JS_GLFW_CONSTANT(KEY_SEMICOLON); 1058 | JS_GLFW_CONSTANT(KEY_EQUAL); 1059 | JS_GLFW_CONSTANT(KEY_A); 1060 | JS_GLFW_CONSTANT(KEY_B); 1061 | JS_GLFW_CONSTANT(KEY_C); 1062 | JS_GLFW_CONSTANT(KEY_D); 1063 | JS_GLFW_CONSTANT(KEY_E); 1064 | JS_GLFW_CONSTANT(KEY_F); 1065 | JS_GLFW_CONSTANT(KEY_G); 1066 | JS_GLFW_CONSTANT(KEY_H); 1067 | JS_GLFW_CONSTANT(KEY_I); 1068 | JS_GLFW_CONSTANT(KEY_J); 1069 | JS_GLFW_CONSTANT(KEY_K); 1070 | JS_GLFW_CONSTANT(KEY_L); 1071 | JS_GLFW_CONSTANT(KEY_M); 1072 | JS_GLFW_CONSTANT(KEY_N); 1073 | JS_GLFW_CONSTANT(KEY_O); 1074 | JS_GLFW_CONSTANT(KEY_P); 1075 | JS_GLFW_CONSTANT(KEY_Q); 1076 | JS_GLFW_CONSTANT(KEY_R); 1077 | JS_GLFW_CONSTANT(KEY_S); 1078 | JS_GLFW_CONSTANT(KEY_T); 1079 | JS_GLFW_CONSTANT(KEY_U); 1080 | JS_GLFW_CONSTANT(KEY_V); 1081 | JS_GLFW_CONSTANT(KEY_W); 1082 | JS_GLFW_CONSTANT(KEY_X); 1083 | JS_GLFW_CONSTANT(KEY_Y); 1084 | JS_GLFW_CONSTANT(KEY_Z); 1085 | JS_GLFW_CONSTANT(KEY_LEFT_BRACKET); 1086 | JS_GLFW_CONSTANT(KEY_BACKSLASH); 1087 | JS_GLFW_CONSTANT(KEY_RIGHT_BRACKET); 1088 | JS_GLFW_CONSTANT(KEY_GRAVE_ACCENT); 1089 | JS_GLFW_CONSTANT(KEY_WORLD_1); 1090 | JS_GLFW_CONSTANT(KEY_WORLD_2); 1091 | 1092 | /* Function keys */ 1093 | JS_GLFW_CONSTANT(KEY_ESCAPE); 1094 | JS_GLFW_CONSTANT(KEY_ENTER); 1095 | JS_GLFW_CONSTANT(KEY_TAB); 1096 | JS_GLFW_CONSTANT(KEY_BACKSPACE); 1097 | JS_GLFW_CONSTANT(KEY_INSERT); 1098 | JS_GLFW_CONSTANT(KEY_DELETE); 1099 | JS_GLFW_CONSTANT(KEY_RIGHT); 1100 | JS_GLFW_CONSTANT(KEY_LEFT); 1101 | JS_GLFW_CONSTANT(KEY_DOWN); 1102 | JS_GLFW_CONSTANT(KEY_UP); 1103 | JS_GLFW_CONSTANT(KEY_PAGE_UP); 1104 | JS_GLFW_CONSTANT(KEY_PAGE_DOWN); 1105 | JS_GLFW_CONSTANT(KEY_HOME); 1106 | JS_GLFW_CONSTANT(KEY_END); 1107 | JS_GLFW_CONSTANT(KEY_CAPS_LOCK); 1108 | JS_GLFW_CONSTANT(KEY_SCROLL_LOCK); 1109 | JS_GLFW_CONSTANT(KEY_NUM_LOCK); 1110 | JS_GLFW_CONSTANT(KEY_PRINT_SCREEN); 1111 | JS_GLFW_CONSTANT(KEY_PAUSE); 1112 | JS_GLFW_CONSTANT(KEY_F1); 1113 | JS_GLFW_CONSTANT(KEY_F2); 1114 | JS_GLFW_CONSTANT(KEY_F3); 1115 | JS_GLFW_CONSTANT(KEY_F4); 1116 | JS_GLFW_CONSTANT(KEY_F5); 1117 | JS_GLFW_CONSTANT(KEY_F6); 1118 | JS_GLFW_CONSTANT(KEY_F7); 1119 | JS_GLFW_CONSTANT(KEY_F8); 1120 | JS_GLFW_CONSTANT(KEY_F9); 1121 | JS_GLFW_CONSTANT(KEY_F10); 1122 | JS_GLFW_CONSTANT(KEY_F11); 1123 | JS_GLFW_CONSTANT(KEY_F12); 1124 | JS_GLFW_CONSTANT(KEY_F13); 1125 | JS_GLFW_CONSTANT(KEY_F14); 1126 | JS_GLFW_CONSTANT(KEY_F15); 1127 | JS_GLFW_CONSTANT(KEY_F16); 1128 | JS_GLFW_CONSTANT(KEY_F17); 1129 | JS_GLFW_CONSTANT(KEY_F18); 1130 | JS_GLFW_CONSTANT(KEY_F19); 1131 | JS_GLFW_CONSTANT(KEY_F20); 1132 | JS_GLFW_CONSTANT(KEY_F21); 1133 | JS_GLFW_CONSTANT(KEY_F22); 1134 | JS_GLFW_CONSTANT(KEY_F23); 1135 | JS_GLFW_CONSTANT(KEY_F24); 1136 | JS_GLFW_CONSTANT(KEY_F25); 1137 | JS_GLFW_CONSTANT(KEY_KP_0); 1138 | JS_GLFW_CONSTANT(KEY_KP_1); 1139 | JS_GLFW_CONSTANT(KEY_KP_2); 1140 | JS_GLFW_CONSTANT(KEY_KP_3); 1141 | JS_GLFW_CONSTANT(KEY_KP_4); 1142 | JS_GLFW_CONSTANT(KEY_KP_5); 1143 | JS_GLFW_CONSTANT(KEY_KP_6); 1144 | JS_GLFW_CONSTANT(KEY_KP_7); 1145 | JS_GLFW_CONSTANT(KEY_KP_8); 1146 | JS_GLFW_CONSTANT(KEY_KP_9); 1147 | JS_GLFW_CONSTANT(KEY_KP_DECIMAL); 1148 | JS_GLFW_CONSTANT(KEY_KP_DIVIDE); 1149 | JS_GLFW_CONSTANT(KEY_KP_MULTIPLY); 1150 | JS_GLFW_CONSTANT(KEY_KP_SUBTRACT); 1151 | JS_GLFW_CONSTANT(KEY_KP_ADD); 1152 | JS_GLFW_CONSTANT(KEY_KP_ENTER); 1153 | JS_GLFW_CONSTANT(KEY_KP_EQUAL); 1154 | JS_GLFW_CONSTANT(KEY_LEFT_SHIFT); 1155 | JS_GLFW_CONSTANT(KEY_LEFT_CONTROL); 1156 | JS_GLFW_CONSTANT(KEY_LEFT_ALT); 1157 | JS_GLFW_CONSTANT(KEY_LEFT_SUPER); 1158 | JS_GLFW_CONSTANT(KEY_RIGHT_SHIFT); 1159 | JS_GLFW_CONSTANT(KEY_RIGHT_CONTROL); 1160 | JS_GLFW_CONSTANT(KEY_RIGHT_ALT); 1161 | JS_GLFW_CONSTANT(KEY_RIGHT_SUPER); 1162 | JS_GLFW_CONSTANT(KEY_MENU); 1163 | JS_GLFW_CONSTANT(KEY_LAST); 1164 | 1165 | /*Modifier key flags*/ 1166 | 1167 | /*If this bit is set one or more Shift keys were held down. */ 1168 | JS_GLFW_CONSTANT(MOD_SHIFT); 1169 | /*If this bit is set one or more Control keys were held down. */ 1170 | JS_GLFW_CONSTANT(MOD_CONTROL); 1171 | /*If this bit is set one or more Alt keys were held down. */ 1172 | JS_GLFW_CONSTANT(MOD_ALT); 1173 | /*If this bit is set one or more Super keys were held down. */ 1174 | JS_GLFW_CONSTANT(MOD_SUPER); 1175 | 1176 | /*Mouse buttons*/ 1177 | JS_GLFW_CONSTANT(MOUSE_BUTTON_1); 1178 | JS_GLFW_CONSTANT(MOUSE_BUTTON_2); 1179 | JS_GLFW_CONSTANT(MOUSE_BUTTON_3); 1180 | JS_GLFW_CONSTANT(MOUSE_BUTTON_4); 1181 | JS_GLFW_CONSTANT(MOUSE_BUTTON_5); 1182 | JS_GLFW_CONSTANT(MOUSE_BUTTON_6); 1183 | JS_GLFW_CONSTANT(MOUSE_BUTTON_7); 1184 | JS_GLFW_CONSTANT(MOUSE_BUTTON_8); 1185 | JS_GLFW_CONSTANT(MOUSE_BUTTON_LAST); 1186 | JS_GLFW_CONSTANT(MOUSE_BUTTON_LEFT); 1187 | JS_GLFW_CONSTANT(MOUSE_BUTTON_RIGHT); 1188 | JS_GLFW_CONSTANT(MOUSE_BUTTON_MIDDLE); 1189 | 1190 | /*Joysticks*/ 1191 | JS_GLFW_CONSTANT(JOYSTICK_1); 1192 | JS_GLFW_CONSTANT(JOYSTICK_2); 1193 | JS_GLFW_CONSTANT(JOYSTICK_3); 1194 | JS_GLFW_CONSTANT(JOYSTICK_4); 1195 | JS_GLFW_CONSTANT(JOYSTICK_5); 1196 | JS_GLFW_CONSTANT(JOYSTICK_6); 1197 | JS_GLFW_CONSTANT(JOYSTICK_7); 1198 | JS_GLFW_CONSTANT(JOYSTICK_8); 1199 | JS_GLFW_CONSTANT(JOYSTICK_9); 1200 | JS_GLFW_CONSTANT(JOYSTICK_10); 1201 | JS_GLFW_CONSTANT(JOYSTICK_11); 1202 | JS_GLFW_CONSTANT(JOYSTICK_12); 1203 | JS_GLFW_CONSTANT(JOYSTICK_13); 1204 | JS_GLFW_CONSTANT(JOYSTICK_14); 1205 | JS_GLFW_CONSTANT(JOYSTICK_15); 1206 | JS_GLFW_CONSTANT(JOYSTICK_16); 1207 | JS_GLFW_CONSTANT(JOYSTICK_LAST); 1208 | 1209 | /*errors Error codes*/ 1210 | 1211 | /*GLFW has not been initialized.*/ 1212 | JS_GLFW_CONSTANT(NOT_INITIALIZED); 1213 | /*No context is current for this thread.*/ 1214 | JS_GLFW_CONSTANT(NO_CURRENT_CONTEXT); 1215 | /*One of the enum parameters for the function was given an invalid enum.*/ 1216 | JS_GLFW_CONSTANT(INVALID_ENUM); 1217 | /*One of the parameters for the function was given an invalid value.*/ 1218 | JS_GLFW_CONSTANT(INVALID_VALUE); 1219 | /*A memory allocation failed.*/ 1220 | JS_GLFW_CONSTANT(OUT_OF_MEMORY); 1221 | /*GLFW could not find support for the requested client API on the system.*/ 1222 | JS_GLFW_CONSTANT(API_UNAVAILABLE); 1223 | /*The requested client API version is not available.*/ 1224 | JS_GLFW_CONSTANT(VERSION_UNAVAILABLE); 1225 | /*A platform-specific error occurred that does not match any of the more specific categories.*/ 1226 | JS_GLFW_CONSTANT(PLATFORM_ERROR); 1227 | /*The clipboard did not contain data in the requested format.*/ 1228 | JS_GLFW_CONSTANT(FORMAT_UNAVAILABLE); 1229 | 1230 | JS_GLFW_CONSTANT(FOCUSED); 1231 | JS_GLFW_CONSTANT(ICONIFIED); 1232 | JS_GLFW_CONSTANT(RESIZABLE); 1233 | JS_GLFW_CONSTANT(VISIBLE); 1234 | JS_GLFW_CONSTANT(DECORATED); 1235 | 1236 | JS_GLFW_CONSTANT(RED_BITS); 1237 | JS_GLFW_CONSTANT(GREEN_BITS); 1238 | JS_GLFW_CONSTANT(BLUE_BITS); 1239 | JS_GLFW_CONSTANT(ALPHA_BITS); 1240 | JS_GLFW_CONSTANT(DEPTH_BITS); 1241 | JS_GLFW_CONSTANT(STENCIL_BITS); 1242 | JS_GLFW_CONSTANT(ACCUM_RED_BITS); 1243 | JS_GLFW_CONSTANT(ACCUM_GREEN_BITS); 1244 | JS_GLFW_CONSTANT(ACCUM_BLUE_BITS); 1245 | JS_GLFW_CONSTANT(ACCUM_ALPHA_BITS); 1246 | JS_GLFW_CONSTANT(AUX_BUFFERS); 1247 | JS_GLFW_CONSTANT(STEREO); 1248 | JS_GLFW_CONSTANT(SAMPLES); 1249 | JS_GLFW_CONSTANT(SRGB_CAPABLE); 1250 | JS_GLFW_CONSTANT(REFRESH_RATE); 1251 | 1252 | JS_GLFW_CONSTANT(CLIENT_API); 1253 | JS_GLFW_CONSTANT(CONTEXT_VERSION_MAJOR); 1254 | JS_GLFW_CONSTANT(CONTEXT_VERSION_MINOR); 1255 | JS_GLFW_CONSTANT(CONTEXT_REVISION); 1256 | JS_GLFW_CONSTANT(CONTEXT_ROBUSTNESS); 1257 | JS_GLFW_CONSTANT(OPENGL_FORWARD_COMPAT); 1258 | JS_GLFW_CONSTANT(OPENGL_DEBUG_CONTEXT); 1259 | JS_GLFW_CONSTANT(OPENGL_PROFILE); 1260 | 1261 | JS_GLFW_CONSTANT(OPENGL_API); 1262 | JS_GLFW_CONSTANT(OPENGL_ES_API); 1263 | 1264 | JS_GLFW_CONSTANT(NO_ROBUSTNESS); 1265 | JS_GLFW_CONSTANT(NO_RESET_NOTIFICATION); 1266 | JS_GLFW_CONSTANT(LOSE_CONTEXT_ON_RESET); 1267 | 1268 | JS_GLFW_CONSTANT(OPENGL_ANY_PROFILE); 1269 | JS_GLFW_CONSTANT(OPENGL_CORE_PROFILE); 1270 | JS_GLFW_CONSTANT(OPENGL_COMPAT_PROFILE); 1271 | 1272 | JS_GLFW_CONSTANT(CURSOR); 1273 | JS_GLFW_CONSTANT(STICKY_KEYS); 1274 | JS_GLFW_CONSTANT(STICKY_MOUSE_BUTTONS); 1275 | 1276 | JS_GLFW_CONSTANT(CURSOR_NORMAL); 1277 | JS_GLFW_CONSTANT(CURSOR_HIDDEN); 1278 | JS_GLFW_CONSTANT(CURSOR_DISABLED); 1279 | 1280 | JS_GLFW_CONSTANT(CONNECTED); 1281 | JS_GLFW_CONSTANT(DISCONNECTED); 1282 | 1283 | // init AntTweakBar 1284 | atb::AntTweakBar::Initialize(target); 1285 | atb::Bar::Initialize(target); 1286 | 1287 | // test scene 1288 | JS_GLFW_SET_METHOD(testScene); 1289 | JS_GLFW_SET_METHOD(testJoystick); 1290 | } 1291 | 1292 | NODE_MODULE(glfw, init) 1293 | } 1294 | 1295 | --------------------------------------------------------------------------------