Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch ferrieux-nacl Excluding Merge-Ins
This is equivalent to a diff from 91a0a93dad to 29517d12f7
2011-10-25
| ||
04:21 | Add a local copy of reference JS demo at same fps. Add an interactive tclsh page for easy timings, i... Leaf check-in: 29517d12f7 user: ferrieux tags: ferrieux-nacl | |
2011-10-18
| ||
22:03 | Streamline demo setup; update README to reflect API changes. check-in: 91aea72dbd user: ferrieux tags: ferrieux-nacl | |
2011-10-07
| ||
21:21 | Fix env.test, when running under wine 1.3 check-in: 78d77f044f user: jan.nijtmans tags: trunk | |
14:49 | merge trunk check-in: 3dcfeb9b27 user: dkf tags: dkf-utf16-branch | |
14:48 | merge trunk check-in: efd220a1ac user: dkf tags: dkf-notifier-poll | |
12:16 | Merge updates from trunk check-in: 59daece720 user: ferrieux tags: ferrieux-nacl | |
12:01 | Fix gcc warnings (discovered with latest mingw, based on gcc 4.6.1) check-in: 91a0a93dad user: jan.nijtmans tags: trunk | |
12:00 | Fix gcc warning (discovered with latest mingw, based on gcc 4.6.1) check-in: 7c93b4fe12 user: jan.nijtmans tags: core-8-5-branch | |
2011-10-06
| ||
21:19 | Reintegrate the compilation of [dict with], which is now usually much faster (but only inside contex... check-in: 81996420e6 user: dkf tags: trunk | |
Changes to ChangeLog.
︙ | ︙ | |||
1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 | * generic/tclDictObj.c: a warning: "Why make your own error * generic/tclScan.c: message? Why?" * generic/tclTest.c: * test/error.test: * test/info.test: * test/scan.test: * unix/tclUnixThrd.h: Remove this unused header file. 2011-04-03 Donal K. Fellows <[email protected]> * generic/tclNamesp.c, generic/tclObj.c, generic/tclPathObj.c: * generic/tclPipe.c, generic/tclPkg.c, generic/tclProc.c: * generic/tclScan.c: More generation of error codes (namespace creation, path normalization, pipeline creation, package handling, | > > > > > | 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 | * generic/tclDictObj.c: a warning: "Why make your own error * generic/tclScan.c: message? Why?" * generic/tclTest.c: * test/error.test: * test/info.test: * test/scan.test: * unix/tclUnixThrd.h: Remove this unused header file. 2011-04-04 Alexandre Ferrieux <[email protected]> * nacl/...: New branch ferrieux-nacl : a port of Tcl to Google's Nacl (Native Client) 2011-04-03 Donal K. Fellows <[email protected]> * generic/tclNamesp.c, generic/tclObj.c, generic/tclPathObj.c: * generic/tclPipe.c, generic/tclPkg.c, generic/tclProc.c: * generic/tclScan.c: More generation of error codes (namespace creation, path normalization, pipeline creation, package handling, |
︙ | ︙ |
Added nacl/Makefile.patch.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 | --- Makefile 2011-04-10 13:21:12.773175132 +0200 +++ tweaked.Makefile 2011-04-10 12:34:27.256426620 +0200 @@ -102,12 +102,17 @@ #CFLAGS = $(CFLAGS_DEBUG) #CFLAGS = $(CFLAGS_OPTIMIZE) #CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = $(CFLAGS_OPTIMIZE) -Wno-long-long -pthread -DNACL -pipe +CFLAGS = $(CFLAGS_OPTIMIZE) -pipe -fvisibility=hidden + + +CFLAGS += -Wno-long-long -pthread -DNACL # Flags to pass to the linker LDFLAGS_DEBUG = LDFLAGS_OPTIMIZE = -LDFLAGS = $(LDFLAGS_OPTIMIZE) -Wl,--export-dynamic +LDFLAGS = $(LDFLAGS_OPTIMIZE) -Wl,--export-dynamic -lm \ + -lppapi \ + -lpthread # To disable ANSI-C procedure prototypes reverse the comment characters on the # following lines: @@ -176,7 +184,7 @@ STLIB_LD = ${AR} cr SHLIB_LD = ${CC} -shared ${CFLAGS} ${LDFLAGS} -SHLIB_CFLAGS = -fPIC -DBUILD_tcl +SHLIB_CFLAGS = -DBUILD_tcl SHLIB_LD_LIBS = ${LIBS} TCL_SHLIB_LD_EXTRAS = @@ -216,7 +224,8 @@ # by hand. #-------------------------------------------------------------------------- -COMPAT_OBJS = waitpid.o fake-rfc2553.o memcmp.o strstr.o strtoul.o strtod.o fixstrtod.o +#COMPAT_OBJS = waitpid.o fake-rfc2553.o memcmp.o strstr.o strtoul.o strtod.o fixstrtod.o +IGNORE_COMPAT_OBJS = waitpid.o fake-rfc2553.o memcmp.o strstr.o strtoul.o strtod.o fixstrtod.o AC_FLAGS = -DPACKAGE_NAME=\"tcl\" -DPACKAGE_TARNAME=\"tcl\" -DPACKAGE_VERSION=\"8.6\" -DPACKAGE_STRING=\"tcl\ 8.6\" -DPACKAGE_BUGREPORT=\"\" -DSTDC_HEADERS=1 -DHAVE_SYS_TYPES_H=1 -DHAVE_SYS_STAT_H=1 -DHAVE_STDLIB_H=1 -DHAVE_STRING_H=1 -DHAVE_INTTYPES_H=1 -DHAVE_STDINT_H=1 -DHAVE_UNISTD_H=1 -DNO_VALUES_H=1 -DHAVE_LIMITS_H=1 -DNO_DLFCN_H=1 -DHAVE_SYS_PARAM_H=1 -DTCL_CFGVAL_ENCODING=\"iso8859-1\" -DSTATIC_BUILD=1 -DHAVE_ZLIB=1 -DMODULE_SCOPE=extern -DTCL_SHLIB_EXT=\".so\" -DTCL_CFG_OPTIMIZED=1 -DTCL_CFG_DEBUG=1 -DTCL_TOMMATH=1 -DMP_PREC=4 -DTCL_WIDE_INT_TYPE=long\ long -DUSEGETWD=1 -DHAVE_MKSTEMP=1 -DHAVE_OPENDIR=1 -DHAVE_STRTOL=1 -DNO_GETWD=1 -DNO_WAIT3=1 -DNO_UNAME=1 -DNO_REALPATH=1 -DNEED_FAKE_RFC2553=1 -DHAVE_SYS_TIME_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_GMTIME_R=1 -DHAVE_LOCALTIME_R=1 -DHAVE_MKTIME=1 -DHAVE_TIMEZONE_VAR=1 -DHAVE_STRUCT_STAT_ST_BLOCKS=1 -DHAVE_STRUCT_STAT_ST_BLKSIZE=1 -DHAVE_BLKCNT_T=1 -DNO_FSTATFS=1 -Dstrtod=fixstrtod -Dsocklen_t=int -DHAVE_INTPTR_T=1 -DHAVE_UINTPTR_T=1 -DNO_UNION_WAIT=1 -DHAVE_SIGNED_CHAR=1 -DHAVE_LANGINFO=1 -DHAVE_MKSTEMPS=1 -DTCL_UNLOAD_DLLS=1 AR = nacl-ar @@ -335,12 +346,13 @@ STUB_LIB_OBJS = tclStubLib.o tclTomMathStubLib.o tclOOStubLib.o ${COMPAT_OBJS} -UNIX_OBJS = tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \ +UNIX_OBJS = naclMissing.o tclUnixChan.o tclUnixEvent.o tclUnixFCmd.o \ tclUnixFile.o tclUnixPipe.o tclUnixSock.o \ tclUnixTime.o tclUnixInit.o tclUnixThrd.o \ tclUnixCompat.o NOTIFY_OBJS = tclUnixNotfy.o +IGN = MAC_OSX_OBJS = tclMacOSXBundle.o tclMacOSXFCmd.o tclMacOSXNotify.o @@ -600,7 +612,7 @@ all: binaries libraries doc packages -binaries: ${LIB_FILE} $(STUB_LIB_FILE) ${TCL_EXE} +binaries: ${LIB_FILE} $(STUB_LIB_FILE) tcl$(arch).nexe libraries: @@ -634,14 +646,36 @@ # Must be empty so it doesn't conflict with rule for ${TCL_EXE} above ${NATIVE_TCLSH}: -Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in - $(SHELL) config.status +init.tcl.c: ../library/init.tcl init.natcl + cat $^ | tools/tocstr > $@ + +tclUnixPort.h: ../unix/tclUnixPort.h tclUnixPort.h.patch + cat ../unix/tclUnixPort.h > tclUnixPort.h + patch -p0 < tclUnixPort.h.patch + +naclMain.o: naclMain.c init.tcl.c + $(CC) -c $(CC_SWITCHES) naclMain.c + +tcl$(arch).nexe: naclMain.o libtcl8.6.a + $(CCPLUS) $^ $(LDFLAGS) -o $@ + +$(TCL_OBJS) $(STUB_LIB_OBJS) $(TCLSH_OBJS) $(TCLTEST_OBJS): tclUnixPort.h + +server: + tclsh trivhttpd.tcl 5103 & + +balls: + google-chrome http://localhost:5103/demo/balls.html + +#Makefile: $(UNIX_DIR)/Makefile.in $(DLTEST_DIR)/Makefile.in +# $(SHELL) config.status #tclConfig.h: $(UNIX_DIR)/tclConfig.h.in # $(SHELL) config.status clean: clean-packages rm -f *.a *.o libtcl* core errs *~ \#* TAGS *.E a.out \ - errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl + errors ${TCL_EXE} ${TCLTEST_EXE} lib.exp Tcl \ + init.tcl.c tclUnixPort.h cd dltest ; $(MAKE) clean distclean: distclean-packages clean @@ -794,7 +826,6 @@ echo "Installing $(STUB_LIB_FILE) to $(LIB_INSTALL_DIR)/"; \ $(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)"/$(STUB_LIB_FILE) ; (cd "$(LIB_INSTALL_DIR)" ; $(RANLIB) $(STUB_LIB_FILE)) ; \ fi - @echo "Installing pkg-config file to $(LIB_INSTALL_DIR)/pkgconfig/" @$(INSTALL_DATA_DIR) $(LIB_INSTALL_DIR)/pkgconfig @$(INSTALL_DATA) tcl.pc $(LIB_INSTALL_DIR)/pkgconfig/tcl.pc @@ -2031,13 +2062,13 @@ html: ${NATIVE_TCLSH} $(BUILD_HTML) - + html-tcl: ${NATIVE_TCLSH} $(BUILD_HTML) --tcl - + html-tk: ${NATIVE_TCLSH} $(BUILD_HTML) --tk - + BUILD_HTML = \ @${NATIVE_TCLSH} $(TOOL_DIR)/tcltk-man2html.tcl \ |
Added nacl/README.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 | NaTcl : Tcl in Nacl Overview -------- NaCl == Native Client is Google's neat sandboxing technology, allowing to run untrusted code compiled natively, in the context of a browser. See http://code.google.com/p/nativeclient/. The idea is that with Tcl running in this context, and a supporting browser (currently, Chrome only; in the future, other browsers too), one could develop client-side code mainly in Tcl, with a very thin layer of JS in the page; so, basically, Tcl to control the HTML5 DOM ! Building Tcl for Nacl --------------------- - install the NaCl SDK at http://code.google.com/chrome/nativeclient/docs/download.html - for now, only use the pepper_14 bundle - add (Nacl-SDK-top-dir)/pepper_14/native_client_sdk_0_5_1052/toolchain/linux_x86/bin to your PATH - cd (Tcl-source-tree)/nacl - run './configure' (which calls ../unix/configure with proper flags, and patches the generated Makefile) - run 'make binaries'. This creates tcl.nmf and tcl32.nexe or tcl64.nexe, depending on the kind of x86 you're currently on. You can also simply type 'make' but the libraries are not usable by NaCl yet (no dynamic linking). - (optional) to also build the other kind, do 'make distclean', then './configure -m32 (or -m64)', then 'make binaries'. The provided manifest file (tcl.nmf) points to both, to be compatible with both builds of Chrome. - run 'make sever'. This starts (on port 5103) a tiny, trivial httpd written in Tcl, whose sole purpose is to server the few demo files. Note that NaCl is explicitly disabled on file:// urls. - (once) open about:flags in Chrome and enable Native Client (note this will be saved in your per-user Chrome preferences and will even survive a Chrome upgrade) - run 'make balls' Overview of the porting method ------------------------------ Nacl comes with a very incomplete libc and set of headers. The strategy, then, is to simply "plug" missing syscalls or library functions with either explicitly failing stubs (returning -1 or NULL, and setting errno) or emulators, and to build a big include file (naclcompat.h) with all the necessary type and macro definitions to compile. Of course, when one of the failing stubs is called at runtime, an error is raised. But one cannot hope much more, it's a sandbox for a reason. This approach allows to compile Tcl for Nacl without changing a single line of the original source distribution; all new things are in the nacl subdir. Also, much is reused from ../unix. Nacl context specifics ---------------------- NaCl lets us run in our sandbox, in a dedicated process; the only possible interactions with the browser process are: - at init time, one of our functions is called - then, each side can post a string message to the other one - on reception, a callback is called with the string as argument. This happens on each side's single thread. This asynchronous communication method ensures that the JS context will never be blocked, whatever the sandboxed child does. For maximal genericity, the way NaTcl "retroacts" on the JS context is by posting back a JS string to eval(). Then you can do whatever you want, including of course arranging for future JS events to call back into NaTcl. See [domset] and [after] (in init.natcl, which is compiled into the binray .nexe) as two very simple examples. In an universe without syscalls, loading other scripts is problematic. To circumvent this (and bootstrap the loading of the main script), [source $url] is reimplemented over a JS XmlHttpRequest. And to preserve the blocking semantics of traditional [source] while XHR is purely async, this implementation is coroutine-based and calls [yield] after starting the request. When the download completes, JS calls back into Tcl to resume the coro, and continue the sequential execution of the Tcl script where it left. This allows for arbitrary series and nesting of [source]. For this reason, the main script is bootstrapped by evaluating: coroutine main_coro source $url This means that all the init code in the script will run in the coro context (for [source]'s benefit, but that could be extended to other things). But once the execution has fallen back out of the main script, hopefully after setting up many (JS) event handlers, it is up to the app to establish other coro contexts if needed. A few things about GUI and blocking: - a simple, ol'good-Tk-style event-driven script will work as usual - lengthy computations on the Tcl side will *not* block the JS's side autonomous GUI elements, thanks to the new async interaction described above - however, to be able ot interrupt the computation from the GUI, or to have Tcl code implement part of the GUI reactions, one must of course let the Tcl code return quickly. - in all cases, [source] works as usual to fetch scripts over HTTP (in the same domain as the page serving the NaTcl plugin). Relative URLs work: [source foo.natcl]. - in all cases, falling back out of the main scripts is equivalent to going back to the Tk eventloop in wish (except it is the JS eventloop). The "Google Balls" demo ----------------------- If you point your chrome to "demo/balls.html" (eg with 'make balls'), you'll get a full NaTcl emulation of the nice Javascript demo at: http://www.html5canvastutorials.com/labs/html5-canvas-google-bouncing-balls This uses a canvas emulation script "canv.natcl", which demonstrates a possible (among many) way of organizing Tcl-JS interaction for graphics. In the balls demo, items are never destroyed nor shuffled, which is a favourable case for lazy recompilation of the JS repaint function (basically the func is written just once, and only the coords stored in a global array get updated, hence allowing for JIT compiling of this function). Perf measurements: the NaTcl version currently costs 3x the CPU of the JS version, so at 40fps it consumes a full core of my 2GHz laptop (against 33% for the JS one). One should note that the pure string API used currently precludes any use of the internal reps of coordinates, so there are many string/integer conversions. To be continued. Comparison with native Tcl/Tk ----------------------------- With the command 'tools/natcl2tk balls.natcl', you can run the same code in pure Tcl/Tk, in a true wish canvas. You can use it for performance and rendering comparisons. Future work ----------- Coming soon: [domget], more [canvas] features, and optimizations ;-) |
Added nacl/configure.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | #! /bin/sh tmp=/tmp/nacl-configure.$$ findarch() { echo -n "Finding default arch ..." >&2 echo "int foo(x) {return x*x;}" > $tmp.c nacl-gcc -c $tmp.c -o $tmp.o kind=`file $tmp.o` /bin/rm $tmp.[co] case "$kind" in *32-bit*) arch=32;; *64-bit*) arch=64;; *) echo "### Cannot compute default arch. Please specify -m32 or -m64.">&2;exit 1;; esac echo " -m$arch" >&2 } case "$1" in -m32) arch=32;; -m64) arch=64;; "") findarch;; *) echo "Usage: ./configure [-m32|-m64]">&2;exit 1;; esac export arch set -ex CC="nacl-gcc -m$arch" CPP="nacl-cpp -m$arch" CFLAGS="-Wno-long-long -pthread -DNACL" ../unix/configure --host nacl --disable-threads --disable-shared rm -f a.out core.* || true cat Makefile > $tmp.mk sed -e '/^CC[ ]*=/ a\ CCPLUS = nacl-g++ -m'$arch'\ arch='$arch' ' < $tmp.mk > Makefile patch -l -p0 < Makefile.patch set +x echo " Makefile generated and patched for NaCl. Ready for 'make' :) ">&2 exit 0 |
Added nacl/demo/NaTk/NaTk.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | <!DOCTYPE html> <html> <head> <script type="text/javascript" src="../loader.js"></script> <script type="text/javascript" src="NaTk.js"></script> </head> <body> <embed name='nacl_module' id='tcl' width=0 height=0 nacl='tcl.nmf' type='application/x-nacl' onload='moduleDidLoad();' verbose=0 source='NaTk.tcl' toplevel='toplevel'/> <div id="toplevel">Loading ...</div> <script id='script' type="text/tcl"> # this script will be evaluated by NaTk button .b -text "Hello, Tk!" -command {alert HELLO} -grid {0 0} frame .f -text "Frame" -grid {1 0} entry .f.e -grid {0 1} label .f.l -text label -textvariable e -grid {0 2} </script> </body> </html> |
Added nacl/demo/NaTk/NaTk.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | function variableTk () { tcl("::oo::" + $(this).attr("id"), 'changed', $(this).val()); } function buttonTk () { tcl("::oo::" + $(this).attr("id"), 'changed'); } function rbuttonTk () { tcl("::oo::" + $(this).attr("id"), 'changed', $(this).val()); } function cbuttonTk () { var val = this.value; if(!$(this).is(":checked")) { val = 0; } tcl("::oo::" + $(this).attr("id"), 'changed', val); } function sliderTk (e, id, ui) { if(e.originalEvent!=undefined) { tcl("::oo::" + id, 'changed', ui.value); } } function autocompleteTk (event,entry) { if(event.originalEvent!=undefined) { tcl("::oo::" + $(entry).attr("id"), 'changed', $(entry).val()); } } |
Added nacl/demo/NaTk/NaTk.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 | # NaTk - Tk emulation under NaTcl # # Colin McCormack proc ::puts {args} { if {[llength $args] == 1} { printf "STDOUT: [lindex $args 0]" } else { printf "[string toupper [lindex $args 0]]: [lindex $args 1]" } } set _packages {mime base64} proc package {cmd args} { printf "PKG: package $cmd $args" switch -- $cmd { require { lassign $args what if {$what in {Tcl Tk TclOO}} return if {$what in $::_packages} return source lib/Utilities/[lindex $args 0].tcl } provide { lassign $args what lappend ::_packages $what } vsatisfies { return 1 } } } source tcllib/textutil/string.tcl source tcllib/textutil/repeat.tcl source tcllib/textutil/adjust.tcl source tcllib/textutil/split.tcl source tcllib/textutil/tabify.tcl source tcllib/textutil/trim.tcl source tcllib/textutil/textutil.tcl source lib/extensions/extend-1.0.tm source lib/extensions/file-1.0.tm source lib/extensions/memoize-1.0.tm source lib/extensions/know-1.0.tm package require Form namespace import oo::* package provide NaTk 1.0 # radiobutton - textvariable command variable value # entry - textvariable validatecommand # scale - command variable # checkbutton - textvariable command variable # button - textvariable command # TextVariable: radiobutton entry checkbutton button # Command: radiobutton scale checkbutton button +validate:entry # Variable: radiobutton scale checkbutton # NaTk - class connecting an interp to an NaTcl window class create ::NaTk { superclass FormClass method toplevel {args} { variable widgets if {[llength $args]} { {*}[dict get $widgets .] {*}$args } else { return [dict get $widgets .] } } method widget {widget} { variable widgets; return [dict get $widgets $widget] } method widgets {} { variable widgets; return $widgets } method mkwidget {type widget args} { variable ns variable interp variable widgets Debug.widget {mkwidget $widget of type $type ($args)} if {$widget ne "."} { set parent [join [lrange [split $widget .] 0 end-1] .] if {$parent eq ""} { set parent . } if {![dict exists $widgets $parent]} { error "Invalid Widget Name - no parent widget '$parent' exists for '$widget'" } set p [list -parent [dict get $widgets $parent]] ;# parent object } elseif {[dict exists $widgets .]} { error "Invalid Widget - Toplevel . already exists" } else { set p {-parent ""} } # construct a widget of given type Debug.widget {::NaTk::$type new -widget $widget $args -interp $interp $p -connection [self]} set cmd [::NaTk::$type new -widget $widget {*}$args -interp $interp {*}$p -connection [self]] return $widget if {[catch { ::NaTk::$type new -widget $widget {*}$args -interp $interp {*}$p -connection [self] } cmd eo]} { Debug.widget {FAILED $widget of type '$type' as obj: $cmd ($eo)} return -options $eo $cmd } else { Debug.widget {created $widget of type '$type' as obj:$cmd} } return $widget } # addwidget - to both Interp and mapping method addwidget {widget cmd} { Interp alias $widget $cmd ;# install widget alias in Interp # remember name<->command mapping variable widgets dict set widgets $widget $cmd dict set widgets $cmd $widget } # delwidget - from both Interp and mapping method delwidget {obj} { Interp alias $widget {} # forget name<->command mapping variable widgets set widget [dict get $widgets $obj] dict unset widgets $widget dict unset widgets $obj } method grid {args} { Debug.grid {NATK GRID: $args} if {[string index [lindex $args 0]] in {x . ^}} { set args [linsert $args 0 configure] } set args [lassign $args command] switch -- $command { anchor - bbox - columnconfigure - info - location - propagate - rowconfigure - size - slaves { set anchor {} set args [lassign $args widget] tailcall [dict get $widgets $widget] grid $command $widget {*}$args } configure - forget - remove - { set slaves {} while {[string index [lindex $args 0] 0] in {x . ^}} { set args [lassign $args slave] lappend slaves $slave } variable widgets set result {} foreach slave $slaves { lappend result $slave lappend result [[dict get $widgets $slave] grid $command $slave {*}$args] } return $result } } } method interp {script} { Debug.interp "INTERP: $script" return [Interp eval $script] } method start {script} { variable verbose set ::nacl::verbose $verbose Debug.interp "INTERP: $script" Interp eval $script my toplevel render } method bgerror {args} { Debug.interp "INTERP BGERROR: $args" ::nacl bgerror {*}$args [Interp info errorstack] } constructor {args} { Debug.widgets {[self] Creating ::NaTk $args} variable safe 0 variable verbose 1 variable {*}$args variable widgets {} variable ns [info object namespace [self]] # create an interpreter for NaTk program variable interp [::interp create {*}[expr {$safe?"-safe":""}] ${ns}::Interp] Interp alias ::bgerror [self] bgerror Interp alias ::alert ::nacl alert my mkwidget toplevel . # install each widget creator as alias in the interp foreach n {button entry label frame checkbutton radiobutton scale select combobox } { Interp alias $n [self] mkwidget $n } Interp alias $n grid [self] grid #::dom get [dict get $::argv script] [self] start } } class create ::NaTk::Widget { variable id props widget interp parent connection rendered method js {} {return ""} method element {} { return $id; #return "document.getElementById('$id')" return "\$('#$id')" ;# if jQuery } # catch unknown methods and palm them off to the parent method unknown {cmd args} { Debug.widgets {unknown $cmd $args} if {[string match <*> $cmd]} { return [{*}$parent $cmd {*}$args] } elseif {[string match .* $cmd]} { return [$cmd {*}$args] } error "Unknown method '$cmd' in [self] of class [info object class [self]]" } method connection {args} { return [{*}$parent {*}$args] } # grid - percolates up to the parent containing a grid method grid {args} { Debug.grid {percolating grid to $parent: grid $args} tailcall $parent grid {*}$args } # gridded - record grid's values method gridded {args} { variable grid if {[llength $args]} { set grid [dict merge $grid $args] } return $grid } # Grid - interpret -grid options to configure as grid commands method Grid {args} { # this widget needs to be gridded set rs 1; set cs 1; set r 0; set c 0 Debug.widgets {config gridding: '$args'} set pargs [lsearch -glob $args -*] if {$pargs > -1} { # we've got extra args set gargs [lrange $args $pargs end] set args [lrange $args 0 $pargs-1] } else { set gargs {} } lassign $args r c rs cs set ga {} foreach {v1 v2} {r row c column rs rowspan cs columnspan} { if {[info exists $v1] && [set $v1] ne ""} { if {$v1 in {rs cs}} { if {[set $v1] <= 0} { set $v1 1 } } else { if {[set $v1] < 0} { set $v1 0 } } lappend ga -$v2 [set $v1] } } Debug.widgets {option -grid: 'grid configure $widget $ga $gargs'} return [my grid configure $widget {*}$ga {*}$gargs] } # style - make an HTML style form method style {gridding} { set attrs {} foreach {css tk} { background-color background color foreground text-align justify vertical-align valign border borderwidth border-color bordercolor width width } { set tkval [dict get? $props $tk] if {$tkval eq ""} continue if {$tk eq "background"} { lappend attrs background "none $tkval !important" if {![dict exists $props bordercolor]} { dict set attrs border-color $tkval } # TODO: background images, URLs } else { dict set attrs $css $tkval } } if {0} { # process -sticky gridding set sticky [dict gridding.sticky?] if {$sticky ne ""} { # we have to use float and width CSS to emulate sticky set sticky [string trim [string tolower $sticky]] set sticky [string map {n "" s ""} $sticky];# forget NS if {[string first e $sticky] > -1} { dict set attrs float "left" } elseif {[string first w $sticky] > -1} { dict set attrs float "right" } if {$sticky in {"ew" "we"}} { # this is the usual case 'stretch me' dict set attrs width "100%" } } } # todo - padding set result "" dict for {n v} $attrs { append result "$n: $v;" } append result [dict gridding.style?] if {$result ne ""} { set result [list style $result] } Debug.widgets {style attrs:($attrs), style:($result)} if {[dict exists $props class]} { lappend result class [dict get $props class] } if {[dict exists $props state] && [dict get $props state] ne "normal" } { lappend result disabled 1 } return $result } # getvalue - return a widget's textvariable or text, where applicable method getvalue {} { if {[dict exists $props textvariable]} { set result [my iget? [dict get $props textvariable]] Debug.widgets {[self] getvalue from textvariable:'[dict get $props textvariable]' value:'$result'} } elseif {[dict exists $props text]} { set result [dict get $props text] Debug.widgets {[self] getvalue from text '$result'} } else { Debug.widgets {[self] getvalue default to ""} set result "" } return $result } # compound - return a widget's image/value compound method compound {args} { if {[llength $args] == 1} { set text [lindex $args 0] Debug.widget {[self] compound explicit '$text'} } else { set text [my getvalue] Debug.widget {[self] compound implicit '$text'} } set text [armour $text] set image [dict get? $props image] if {$image ne ""} { set image [$image render] } set result "" switch -- [dict get? $props compound] { left { set result $image$text } right { set result $text$image } center - top { set result "$image[my <br>]$text" } bottom { set result "$text[my <br>]$image" } none - default { # image instead of text if {$image ne ""} { set result "$image" } else { set result "$text" } } } Debug.widget {[self] compound ($args) -> $result} return $result } # access interp variables method iset {n v} { Debug.interp {iset '$n' <- '$v' traces:([{*}$interp eval [list trace info variable $n]]) ([lrange [info level -1] 0 1])} return [{*}$interp eval [list ::set $n $v]] } method iget? {n} { try { Debug.widgets {iget $n: {*}$interp eval ::if \{\[info exists $n\]\} \{set $n\}} set result [{*}$interp eval ::if \{\[info exists $n\]\} \{set $n\}] } on error {e eo} { set result "" } Debug.interp {iget '$n' -> '$result' ([lrange [info level -1] 0 1])} return $result } method iget {n} { try { set result [{*}$interp eval [list ::set $n]] } on error {e eo} { set result "" } Debug.interp {iget '$n' -> '$result' ([lrange [info level -1] 0 1])} return $result } method iexists {n} { set result [{*}$interp eval [list ::info exists $n]] Debug.interp {iexists '$n' -> $result} return $result } # itrace - trace an Interp variable method itrace {what args} { variable trace ;# set of active traces for this widget if {[llength $args]} { # add a trace dict set trace $what $args {*}$interp eval [list trace add variable $what write $args] Debug.interp {itrace add $what $args: ([{*}$interp eval [list trace info variable $what]])} } elseif {[dict exists $trace $what]} { {*}$interp eval [list trace remove variable $what write [dict get $trace $what]] Debug.interp {itrace removed $what $args ([dict get $trace $what]) leaving ([{*}$interp eval [list trace info variable $what]])} dict unset trace $what } } # Configure - reflect configuration in $props dict # give trace-effect to -textvariable and -variable opts method Configure {args} { # set configuration opts Debug.widgets {[info coroutine] Configure [self] ($args)/[llength $args]} if {[llength $args]%2} { error "Configure requires even number of args" } # clean the '-' prefix from property names dict for {n v} $args { if {[string match -* $n]} { dict unset args $n dict set args [string trim $n -] $v } } dict for {n v} $args { switch -- $n { variable - textvariable { # remove any old traces first if {[dict get? $props $n] ne ""} { my itrace [dict get $props $n] } dict set props $n $v if {$v ne ""} { # (re-)establish variable trace Debug.widgets {tracking -$n '$v' changes} if {![my iexists $v]} { # create variable if necessary {*}$interp eval [list ::variable ::$v] } if {[dict exists $args text]} { my iset $v [dict get $args text] } # track changes to textvariable my itrace [dict get $props $n] $widget $n } else { catch {dict unset props $n} } } grid { my Grid {*}$v } default { # normal old configuration variable dict set props $n $v } } } } method configure {args} { switch -- [llength $args] { 0 { # get the names of all configuration opts set _result {}; foreach v $props { lappend result -$v [dict get $props $v] } return $result } 1 { # get the value of a single configuration opt set v [string trimleft [llength $args 0] -] return [dict get $props $v] } default { # handle configure with sensitivity to -command, -variable, etc tailcall my Configure {*}$args } } } destructor { $connection delwidget [self] ;# remove full widget name } method id {} { return $id } method nacl {args} { if {!$rendered} return set script [join $args \;\n] ::nacl js $script } method render {args} { incr rendered } constructor {args} { variable grid {} set id [namespace tail [self]] set rendered 0 ;# not yet rendered # get structural vars from NaTk mkwidget foreach v {widget interp parent connection} { set $v [dict get $args -$v] dict unset args -$v } Debug.widgets "create $widget ([self]) parent: $parent" # add widget to Interp and mapping $connection addwidget $widget [self] set props {} ;# no properties yet variable trace {} ;# no traces yet my Configure {*}$args ;# fill up props } } class create ::NaTk::button { superclass ::NaTk::Widget variable id props widget interp parent connection rendered # button - textvariable command # textvariable - interp's textvariable has changed method textvariable {} { variable ignore; if {$ignore} return set val [my iget [dict get $props textvariable]] my nacl [my element].innerHTML='[my compound]' } method changed {} { set cmd [dict get? $props command] if {$cmd ne ""} { {*}$interp eval $cmd } } method render {args} { next set event [list onclick "tcl(\"[self]\",\"changed\");"] return [my <button> $id id $id type button class button {*}$event {*}[my style $args] [my compound]] } constructor {args} { next justify left {*}$args } } class create ::NaTk::entry { superclass ::NaTk::Widget variable id props widget interp parent connection rendered # entry - textvariable validatecommand # textvariable - interp's textvariable has changed # reflect change onto browser widget method textvariable {args} { variable ignore; if {$ignore} return set val [my iget [dict get $props textvariable]] my nacl [my element].value='$val' } method changed {value} { # the entry value has changed # TODO call validation cmd variable ignore; incr ignore my iset [dict get $props textvariable] $value incr ignore -1 } method render {args} { next Debug.widgets {[info coroutine] rendering Entry [self]} switch -- [dict get? $props type] { password { set tag <password> } date { set tag <text> #append js [my element].datepicker(); } default { set tag <text> } } set event [list onchange "tcl(\"[self]\",\"changed\",tclEsc([my element].value));return false;"] set result [my $tag $id id $id class var {*}$event {*}[my style $args] size [dict get $props width] [tclarmour [my getvalue]]] return $result } constructor {args} { variable ignore 1 next {*}[dict merge { justify left state normal width 16 } $args] if {![dict exists $props textvariable]} { my Configure textvariable [lindex [split $widget .] end] } if {[dict exists $props show] && ![dict exists $props type]} { my configure -type password } incr ignore -1 } } class create ::NaTk::label { superclass ::NaTk::Widget variable id props widget interp parent connection rendered # label - textvariable text method textvariable {args} { variable ignore; if {$ignore} return Debug.widget {label $id: getvalue: '[my getvalue]'} my nacl [my element].innerHTML='[my compound]' } method render {args} { next return [my <div> id $id class label {*}[my style $args] [my compound]] } constructor {args} { variable ignore; incr ignore next justify left {*}$args if {![dict exists $props textvariable]} { my Configure textvariable [lindex [split $widget .] end] } incr ignore -1 } } class create ::NaTk::checkbutton { superclass ::NaTk::Widget variable id props widget interp parent connection rendered # checkbutton - textvariable command variable method textvariable {} { variable ignore; if {$ignore} return set val [my iget [dict get $props textvariable]] my nacl [my element].whatever } # changed - button state in browser - reflect to var/command method changed {value} { variable ignore; incr ignore my iset [dict get $props variable] $value incr ignore -1 if {[dict exists $props command]} { {*}$interp eval [dict get $props command] } } method js {} { return "\$('#$id'>:checkbox').change(cbuttonTk);" } method render {args} { next Debug.widgets {checkbutton render: getting '[dict get $props variable]' == [my iget [dict get $props variable]]} set val [my iget [dict get $props variable]] if {$val ne "" && $val} { set checked 1 } else { set checked 0 } Debug.widgets {[self] checkbox render: checked:$checked} return [my <checkbox> $id id $id {*}[my style $args] checked $checked [tclarmour [my compound]]] } constructor {args} { variable ignore 0 next justify left {*}$args if {![dict exists $props variable]} { my Configure variable [lindex [split $widget .] end] } } } # rbC - pseudo-widget which handles change events for a set of # radiobuttons sharing the same variable. class create ::NaTk::rb { superclass ::NaTk::Widget variable id props widget interp parent connection rendered method render {args} { next error "Can't render an rbC" } constructor {args} { next {*}$args ;# set up traces etc } } class create ::NaTk::radiobutton { superclass ::NaTk::Widget variable id props widget interp parent connection rendered # radiobutton - textvariable command variable value method textvariable {} { variable ignore; if {$ignore} return set val [my iget [dict get $props textvariable]] my nacl [my element].whatever } method variable {} { set val [my iget [dict get $props textvariable]] my nacl [my element].whatever } # changed - button state in browser - reflect to var/command method changed {value} { variable ignore; incr ignore my iset [dict get $props variable] $value incr ignore -1 if {[dict exists $props command]} { {*}$interp eval [dict get $props command] } } method js {} { return "[my element].click(rbuttonTk);" } method update {args} { Debug.widgets {radiobutton render: getting '[dict get $props variable]' == [my iget [dict get $props variable]]} set checked 0 set var [dict get $props variable] if {[my iexists $var]} { set val [my iget $var] if {$val eq [dict get $props value]} { set checked 1 } } Debug.widgets {[self] radiobox render: checked:$checked} set result [my <radio> [[my connection rbvar $var] widget] id $id class rbutton {*}[my style $args] checked $checked value [dict get $props value] [dict args.label?]] Debug.widgets {RADIO html: $result} return $result } method render {args} { next set label [tclarmour [my compound]] return [my update {*}$args label $label] } constructor {args} { variable ignore 0 next justify left {*}$args if {![dict exists $props variable]} { my Configure variable selectedButton } } } class create ::NaTk::scale { superclass ::NaTk::Widget variable id props widget interp parent connection rendered # scale - command variable # scale value has changed in browser method changed {value} { variable ignore; incr ignore my iset [dict get $props variable] $value incr ignore -1 if {[dict exists $props command]} { {*}$interp eval [dict get $props command] } } # variable - interp var has changed - reflect to browser widget method variable {} { variable ignore; if {$ignore} return set val [my iget [dict get $props variable]] my nacl [my element].whatever } # js - javascript to track changes to the browser widget method js {} { # need to generate the slider interaction lappend opts orientation '[dict get $props orient]' lappend opts min [dict get $props from] lappend opts max [dict get $props to] lappend opts value [my iget [dict get $props variable]] lappend opts change [string map [list %ID% $id] { function (event,ui) { sliderTk(event, '%ID%', ui); } }] return "[my element].slider([::nacl opts {*}$opts]); [my element].change(sliderTk);" } method render {args} { next Debug.widgets {scale $id render $args} set result "" if {[dict get? $props label] ne ""} { set result [my <label> [dict get $props label]] } append result [my <div> id $id class slider {*}[my style $args] {}] Debug.widgets {scale $id rendered '$result'} return $result } constructor {args} { variable ignore 0 set var [lindex [split [dict get $args -name] .] end] next {*}[dict merge [list -variable $var] { justify left state active label "" command "" -length 100 -width 10 -showvalue 0 -from 0 -to 100 -tickinterval 0 -orient horizontal } $args] } } class create ::NaTk::select { superclass ::NaTk::Widget variable id props widget interp parent connection rendered method textvariable {} { variable ignore; if {$ignore} return set val [my iget [dict get $props textvariable]] my nacl [my element].value='$val' } # variable - interp var has changed - reflect to browser widget method variable {} { variable ignore; if {$ignore} return set val [my iget [dict get $props variable]] my nacl [my element].value='$val' } # select value has changed in browser method changed {value} { variable ignore; incr ignore my iset [dict get $props variable] $value incr ignore -1 if {[dict exists $props command]} { {*}$interp eval [dict get $props command] } } method render {args} { next set var [dict get $props textvariable] if {[my iexists $var]} { set val [my iget $var] } set values [dict get $props values] Debug.widgets {select: val=$val values=$values} foreach opt $values { lappend opts [my <option> value [tclarmour $opt]] } set opts [join $opts \n] set class {variable ui-widget ui-state-default ui-corner-all} if {[dict exists $props combobox] && [dict get $props combobox] } { lappend class combobox } set event [list onclick "tcl(\"[self]\",\"changed\",[my element].value);return false;"] return [my <select> $id id $id {*}$event class [join $class] {*}[my style $args] $opts] } constructor {args} { variable ignore 0 next justify left {*}$args if {![dict exists $props variable]} { my Configure variable [lindex [split $widget .] end] } } } class create ::NaTk::combobox { superclass ::NaTk::select variable id props widget interp parent connection rendered method render {} { next Debug.widgets {combobox} set result [next] my nacl [my element].combobox() return $result } constructor {args} { next {*}$args -combobox 1 } } # grid store grid info in an x/y array gridLayout(column.row) class create ::NaTk::grid { variable id props widget interp parent connection rendered # traverse grid looking for changes. method changes {r} { if {[dict exists $r -repaint]} { # repaint short-circuits change search #Debug.grid {Grid '[namespace tail [self]]' repainting} return [list $r {}] } variable grid;variable oldgrid #Debug.grid {Grid detecting changes: '[namespace tail [self]]'} # look for modified grid entries, these will cause a repaint dict for {row rval} $grid { dict for {col val} $rval { if {$val ne [dict oldgrid.$row.$col?]} { # grid has changed ... force reload Debug.grid {[namespace tail [self]] repainting} dict set r -repaint 1 return [list $r {}] ;# return the dict of changes by id } } } if {[dict size [dict ni $oldgrid [dict keys $grid]]]} { # a grid element has been deleted Debug.grid {Grid repainting: '[namespace tail [self]]'} dict set r -repaint 1 return [list $r {}] ;# return the dict of changes by id } set changes {} dict for {row rval} $grid { dict for {col val} $rval { dict with val { set type [uplevel 1 [list $widget type]] set changed {} switch -- $type { accordion - notebook - frame { # propagate change request to geometry managing widgets #Debug.grid {Grid changing $type '$widget' at ($row,$col)} set changed [lassign [uplevel 1 [list $widget changes $r]] r] if {[dict exists $r -repaint]} { Debug.grid {Grid '[namespace tail [self]]' subgrid repaint $type '$widget'} return [list $r {}] ;# repaint } else { #Debug.grid {Grid '[namespace tail [self]]' subgrid [string totitle $type] '$widget' at ($row,$col) ($val) -> ($changed)} } } default { if {[uplevel 1 [list $widget changed?]]} { Debug.grid {[namespace tail [self]] changing: ($row,$col) $widget [uplevel 1 [list $widget type]] reports it's changed} uplevel 1 [list $widget reset] set changed $widget lappend changed [uplevel 1 [list $widget wid]] lappend changed [uplevel 1 [list $widget update]] lappend changed [uplevel 1 [list $widget type]] Debug.grid {Grid '[namespace tail [self]]' accumulate changes to [string totitle $type] '$widget' at ($row,$col) ($val) -> ($changed)} } } } lappend changes {*}$changed set r [uplevel 1 [list $widget js $r]] } } } return [list $r {*}$changes] ;# return the dict of changes by id } method changed? {} {return 1} # render - construct a grid's <table> method grid_render {args} { variable maxrows; variable maxcols; variable grid Debug.grid {grid render [dict keys grid] over $maxrows/$maxcols} set rows {} ;# accumulate rows for {set row 0} {$row < $maxrows} {incr row} { set cols {} ;# accumulate cols for {set col 0} {$col < $maxcols} {} { set columnspan 1 if {[dict exists $grid $row $col]} { set el [dict get $grid $row $col] dict with el { Debug.grid {'[namespace tail [self]]' grid rendering $widget/$object} for {set rt $row} {$rt < $rowspan} {incr rt} { set rspan($widget,[expr {$row + $rt}].$col) 1 for {set ct $col} {$ct < $columnspan} {incr ct} { set rspan($widget,$rt.[expr {$col + $ct}]) 1 } } if {$rowspan != 1} { set rowspan [list rowspan $rowspan] } else { set rowspan {} } lappend cols [my <td> id [my id]_${row}_$col colspan $columnspan {*}$rowspan [$object render style $style sticky $sticky]] } incr col $columnspan } else { # empty cell if {[info exists widget] && ![info exists rspan($widget,$row.$col)] } { lappend cols [my <td> id [my id]_${row}_$col " "] } incr col $columnspan } } # now we have a complete row - accumulate it # align and valign not allowed here lappend rows [my <tr> id [my id]_$row style width:100% [join $cols \n]] } variable oldgrid $grid ;# record the old grid set content [my <tbody> [join $rows \n]] dict set args width 100% set border [dict get? $props border] if {$border eq ""} { set b {} } elseif {[string is integer -strict $border]} { set b [list border ${border}px] } else { set b [list border $border] } set content [my <table> class grid {*}$b {*}[my style $args] $content] Debug.grid {Grid '[namespace tail [self]]' rendered ($content)} return $content } method grid_js {} { set result "" variable grid dict for {rc row} $grid { dict for {cc col} $row { append result [[dict get $col object] js] } } return $result } method grid_anchor {master {anchor ""}} { if {$master ne $widget} { return [$parent grid anchor $master {*}$args] } } method grid_bbox {master args} { if {$master ne $widget} { return [$parent grid bbox $master {*}$args] } } method grid_columnconfigure {master index args} { if {$master ne $widget} { return [$parent grid columnconfigure $master $index {*}$args] } } method grid_location {master x y} { if {$master ne $widget} { return [$parent grid location $master $x $y] } } method grid_propagate {master boolean} { if {$master ne $widget} { return [$parent grid propagate $master $boolean] } } method grid_rowconfigure {master index args} { if {$master ne $widget} { return [$parent grid rowconfigure $master $index {*}$args] } } method grid_size {master} { if {$master ne $widget} { return [$parent grid size $master] } variable maxcols; variable maxrows return [list $maxcols $maxrows] } method grid_slaves {master {option all} {value 0}} { if {$master ne $widget} { return [$parent grid slaves $master $option $value] } variable grid switch -- $option { -row { dict for {col v} [dict get $grid $value] { lappend result [dict get $v widget] } } -column { dict for {row v} $grid { if {[dict exists $v $value]} { lappend result [dict get $v $value widget] } } } default { dict for {row c} $grid { dict for {col v} $c { lappend result [dict get $v widget] } } } } return $result } method grid_forget {slave} { if {$slave eq $widget} { return [$parent grid forget $widget {*}$args] } } method grid_info {slave} { if {$slave eq $widget} { return [$parent grid info $widget {*}$args] } } method grid_remove {slave} { if {$slave eq $widget} { return [$parent grid remove $widget {*}$args] } [$connection widget $slave] hide } method grid_configure {slave args} { if {$slave eq $widget} { return [$parent grid configure $widget {*}$args] } # set defaults set column 0 set row 0 set columnspan 1 set rowspan 1 set sticky "" set in "" set style "" foreach {var val} $args { set [string trim $var -] $val } variable maxcols set width [expr {$column + $columnspan}] if {$width > $maxcols} { set maxcols $width } variable maxrows set height [expr {$row + $rowspan}] if {$height > $maxrows} { set maxrows $height } set object [$connection widget $slave] variable grid dict set grid $row $column [list widget $slave columnspan $columnspan rowspan $rowspan sticky $sticky in $in style $style object $object] $object gridded columnspan $columnspan rowspan $rowspan sticky $sticky in $in style $style Debug.grid {[namespace tail [self]] configure gridding $slave/$object} return $slave } method grid {cmd args} { Debug.grid {[self] Calling grid_$cmd $args} tailcall my grid_$cmd {*}$args } constructor {args} { Debug.grid {[self] GRID constructing ($args)} variable maxcols 1 variable maxrows 1 variable border 0 variable grid {} variable connection [dict get $args -connection] next {*}$args Debug.grid {[self] GRID constructed ($args)} } } # frame widget class create ::NaTk::frame { superclass ::NaTk::Widget mixin ::NaTk::grid variable id props widget interp parent connection rendered # render widget method render {args} { next Debug.widgets {Frame [namespace tail [self]] render} if {[dict exists $props div] || [dict get? $props text] eq "" } { append content \n [my grid_render {*}$args] return [my <div> id $id class frame {*}[my style $args] $content] } else { set label [dict get? $props text] if {$label ne ""} { set content [my <legend> [tclarmour $label]] } append content \n [my grid_render {*}$args] return [my <fieldset> $id class frame {*}[my style $args] -raw 1 $content] } } destructor { # TODO destroy all child widgets next } constructor {args} { Debug.widgets {creating Frame [self]} next -border 0 {*}$args Debug.widgets {created Frame [self]} } } # toplevel widget class create ::NaTk::toplevel { superclass ::NaTk::Widget mixin ::NaTk::grid variable id props widget interp parent connection rendered # render widget method render {args} { next Debug.widgets {[namespace tail [self]] toplevel render} my nacl toplevel.innerHTML=[::nacl jsquote [my <form> form_$id onsubmit "return false;" [my grid_render {*}$args]]] my nacl [::nacl jsquote [my grid_js]] } constructor {args} { next -titlebar 1 -menubar 1 -border 0 -toolbar 1 -location 1 -scrollbars 1 -status 1 -resizable 1 {*}$args set id toplevel } } Debug on form Debug on widgets Debug on widget Debug on interp Debug on grid set ::nacl::verbose 1 # fetch all the <script> elements which are type text/tcl # pass them as one big string to the NaTk object for evaluation. ::nacl js "runTclScripts('[::NaTk new] start')" |
Added nacl/demo/NaTk/tcl.nmf.
> > > > > > | 1 2 3 4 5 6 | { "nexes": { "x86-32": "../tcl32.nexe", "x86-64": "../tcl64.nexe", } } |
Added nacl/demo/a.natcl.
> > > | 1 2 3 | printf "I'm a.natcl" source c.natcl |
Added nacl/demo/b.natcl.
> > | 1 2 | printf "I'm b.natcl" |
Added nacl/demo/balls.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <!DOCTYPE html> <html> <head> <script type="text/javascript" src="loader.js"></script> </head> <body> <div id="listener"> <script type="text/javascript"> document.getElementById('listener') .addEventListener('load', moduleDidLoad, true); </script> <embed name='nacl_module' id='tcl' width=0 height=0 src='../tcl.nmf' type='application/x-nacl' verbose=0 source='balls.natcl'> <canvas id="canvas" width="578" height="200"></canvas> <h2>Status</h2> <div id="modstatus">NO-STATUS</div> </embed> </div> <p style="font-size : smaller;"> To run this demo, you need <ul style="font-size : smaller;"> <li> An x86-family processor</li> <li> Chrome 15 or higher</li> <li> Enabled "Native Client" item in about:flags</li> <li> if everything else fails, try the Nacl demos at <a href="http://code.google.com/chrome/nativeclient/docs/examples.html">http://code.google.com/chrome/nativeclient/docs/examples.html</a></li> </ul> </p> <script type="text/javascript"> var statusField = document.getElementById('modstatus'); var canvas = document.getElementById('canvas'); var context=canvas.getContext("2d"); var repaint = function () {}; var canvcoords = []; function updateCoords(ar) { var i,n; n=ar.length; for(i=0;i<n;i+=2) canvcoords[ar[i]]=ar[i+1]; } </script> </body> </html> |
Added nacl/demo/balls.natcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 | source canv.natcl #set ::canv_verbose 1 domset statusField "Running..." # will be retrieved by [domget] set width 578 set height 200 # animation globals set t 0 set frameInterval 25 # ball globals set ballRadius 10 # physics global set collisionDamper 0.3 set floorFriction [expr {0.0005*$frameInterval}] set mouseForceMultiplier [expr {1.0*$frameInterval}] set restoreForce [expr {0.002*$frameInterval}] set mouseX 99999 set mouseY 99999 set balls {} set blue "#3A5BCD" set red "#EF2B36" set yellow "#FFC636" set green "#02A817" proc newball {x y vx vy col} { set id [canv_create circle $x $y $::ballRadius -fill $col -outline ""] set ::b($id) [list $x $y $vx $vy $x $y] lappend ::balls $id } # G newball 173 63 0 0 $blue newball 158 53 0 0 $blue newball 143 52 0 0 $blue newball 130 53 0 0 $blue newball 117 58 0 0 $blue newball 110 70 0 0 $blue newball 102 82 0 0 $blue newball 104 96 0 0 $blue newball 105 107 0 0 $blue newball 110 120 0 0 $blue newball 124 130 0 0 $blue newball 139 136 0 0 $blue newball 152 136 0 0 $blue newball 166 136 0 0 $blue newball 174 127 0 0 $blue newball 179 110 0 0 $blue newball 166 109 0 0 $blue newball 156 110 0 0 $blue # O newball 210 81 0 0 $red newball 197 91 0 0 $red newball 196 103 0 0 $red newball 200 116 0 0 $red newball 209 127 0 0 $red newball 223 130 0 0 $red newball 237 127 0 0 $red newball 244 114 0 0 $red newball 242 98 0 0 $red newball 237 86 0 0 $red newball 225 81 0 0 $red # O set oOffset 67 newball [expr {$oOffset + 210}] 81 0 0 $yellow newball [expr {$oOffset + 197}] 91 0 0 $yellow newball [expr {$oOffset + 196}] 103 0 0 $yellow newball [expr {$oOffset + 200}] 116 0 0 $yellow newball [expr {$oOffset + 209}] 127 0 0 $yellow newball [expr {$oOffset + 223}] 130 0 0 $yellow newball [expr {$oOffset + 237}] 127 0 0 $yellow newball [expr {$oOffset + 244}] 114 0 0 $yellow newball [expr {$oOffset + 242}] 98 0 0 $yellow newball [expr {$oOffset + 237}] 86 0 0 $yellow newball [expr {$oOffset + 225}] 81 0 0 $yellow # G newball 370 80 0 0 $blue newball 358 79 0 0 $blue newball 346 79 0 0 $blue newball 335 84 0 0 $blue newball 330 98 0 0 $blue newball 334 111 0 0 $blue newball 348 116 0 0 $blue newball 362 109 0 0 $blue newball 362 94 0 0 $blue newball 355 128 0 0 $blue newball 340 135 0 0 $blue newball 327 142 0 0 $blue newball 325 155 0 0 $blue newball 339 165 0 0 $blue newball 352 166 0 0 $blue newball 367 161 0 0 $blue newball 371 149 0 0 $blue newball 366 137 0 0 $blue # L newball 394 49 0 0 $green newball 381 50 0 0 $green newball 391 61 0 0 $green newball 390 73 0 0 $green newball 392 89 0 0 $green newball 390 105 0 0 $green newball 390 118 0 0 $green newball 388 128 0 0 $green newball 400 128 0 0 $green # E newball 426 101 0 0 $red newball 436 98 0 0 $red newball 451 95 0 0 $red newball 449 83 0 0 $red newball 443 78 0 0 $red newball 430 77 0 0 $red newball 418 82 0 0 $red newball 414 93 0 0 $red newball 412 108 0 0 $red newball 420 120 0 0 $red newball 430 127 0 0 $red newball 442 130 0 0 $red newball 450 125 0 0 $red set oldcnt 0 proc computeFps {} { set fps [expr $::cnt-$::oldcnt] set ::oldcnt $::cnt domset statusField "Running - $fps fps" } set cnt 0 proc updateStage {} { incr ::cnt foreach id $::balls { foreach {x y vx vy rx ry} $::b($id) break # set ball position based on velocity set x [expr {$x+$vx}] set y [expr {$y+$vy}] # restore forces if {$x>$rx} { set vx [expr {$vx-$::restoreForce}] } else { set vx [expr {$vx+$::restoreForce}] } if {$y>$ry} { set vy [expr {$vy-$::restoreForce}] } else { set vy [expr {$vy+$::restoreForce}] } # mouse forces set distX [expr {$x-$::mouseX}] set distY [expr {$y-$::mouseY}] set radius [expr {hypot($distX,$distY)}] set totalDist [expr {abs($distX)+abs($distY)}] set forceX [expr {(abs($distX)/double($totalDist))*(1.0/$radius)*$::mouseForceMultiplier}] set forceY [expr {(abs($distY)/double($totalDist))*(1.0/$radius)*$::mouseForceMultiplier}] if {$distX>0} { # mouse is left of ball set vx [expr {$vx+$forceX}] } else { set vx [expr {$vx-$forceX}] } if {$distY>0} { # mouse is on top of ball set vy [expr {$vy+$forceY}] } else { set vy [expr {$vy-$forceY}] } # floor friction if {$vx>0} { set vx [expr {$vx-$::floorFriction}] } elseif {$vx<0} { set vx [expr {$vx+$::floorFriction}] } if {$vy>0} { set vy [expr {$vy-$::floorFriction}] } elseif {$vy<0} { set vy [expr {$vy+$::floorFriction}] } # floor condition if {$y>($::height-$::ballRadius)} { set y [expr {$::height-$::ballRadius-2}] set vy [expr {-$vy*(1.0-$::collisionDamper)}] } # ceiling condition if {$y<$::ballRadius} { set y [expr {$::ballRadius+2}] set vy [expr {-$vy*(1.0-$::collisionDamper)}] } # right wall condition if {$x>($::width-$::ballRadius)} { set x [expr {$::width-$::ballRadius-2}] set vx [expr {-$vx*(1.0-$::collisionDamper)}] } # left wall condition if {$x<$::ballRadius} { set x [expr {$::ballRadius+2}] set vx [expr {-$vx*(1.0-$::collisionDamper)}] } set ::b($id) [list $x $y $vx $vy $rx $ry] canv_moveto $id [expr {int($x+0.5)}] [expr {int($y+0.5)}] } } proc motioncb {x y} { set ::mouseX $x set ::mouseY $y } proc entercb {} { printf "Enter Canvas !!!" } proc leavecb {} { printf "Leave Canvas !!!" set ::mouseX 99999 set ::mouseY 99999 } canv_bind <Motion> motioncb canv_bind <Enter> entercb canv_bind <Leave> leavecb every $frameInterval updateStage every 1000 computeFps |
Added nacl/demo/ballsjs.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | <!DOCTYPE HTML> <html> <head> <style> body { margin: 0px; padding: 0px; } #myCanvas { border: 1px solid #9C9898; } </style> <script src="kinetic2d-v1.0.3.js"> </script> <script> function initBalls(){ balls = []; var blue = "#3A5BCD"; var red = "#EF2B36"; var yellow = "#FFC636"; var green = "#02A817"; // G balls.push(new Ball(173, 63, 0, 0, blue)); balls.push(new Ball(158, 53, 0, 0, blue)); balls.push(new Ball(143, 52, 0, 0, blue)); balls.push(new Ball(130, 53, 0, 0, blue)); balls.push(new Ball(117, 58, 0, 0, blue)); balls.push(new Ball(110, 70, 0, 0, blue)); balls.push(new Ball(102, 82, 0, 0, blue)); balls.push(new Ball(104, 96, 0, 0, blue)); balls.push(new Ball(105, 107, 0, 0, blue)); balls.push(new Ball(110, 120, 0, 0, blue)); balls.push(new Ball(124, 130, 0, 0, blue)); balls.push(new Ball(139, 136, 0, 0, blue)); balls.push(new Ball(152, 136, 0, 0, blue)); balls.push(new Ball(166, 136, 0, 0, blue)); balls.push(new Ball(174, 127, 0, 0, blue)); balls.push(new Ball(179, 110, 0, 0, blue)); balls.push(new Ball(166, 109, 0, 0, blue)); balls.push(new Ball(156, 110, 0, 0, blue)); // O balls.push(new Ball(210, 81, 0, 0, red)); balls.push(new Ball(197, 91, 0, 0, red)); balls.push(new Ball(196, 103, 0, 0, red)); balls.push(new Ball(200, 116, 0, 0, red)); balls.push(new Ball(209, 127, 0, 0, red)); balls.push(new Ball(223, 130, 0, 0, red)); balls.push(new Ball(237, 127, 0, 0, red)); balls.push(new Ball(244, 114, 0, 0, red)); balls.push(new Ball(242, 98, 0, 0, red)); balls.push(new Ball(237, 86, 0, 0, red)); balls.push(new Ball(225, 81, 0, 0, red)); // O var oOffset = 67; balls.push(new Ball(oOffset + 210, 81, 0, 0, yellow)); balls.push(new Ball(oOffset + 197, 91, 0, 0, yellow)); balls.push(new Ball(oOffset + 196, 103, 0, 0, yellow)); balls.push(new Ball(oOffset + 200, 116, 0, 0, yellow)); balls.push(new Ball(oOffset + 209, 127, 0, 0, yellow)); balls.push(new Ball(oOffset + 223, 130, 0, 0, yellow)); balls.push(new Ball(oOffset + 237, 127, 0, 0, yellow)); balls.push(new Ball(oOffset + 244, 114, 0, 0, yellow)); balls.push(new Ball(oOffset + 242, 98, 0, 0, yellow)); balls.push(new Ball(oOffset + 237, 86, 0, 0, yellow)); balls.push(new Ball(oOffset + 225, 81, 0, 0, yellow)); // G balls.push(new Ball(370, 80, 0, 0, blue)); balls.push(new Ball(358, 79, 0, 0, blue)); balls.push(new Ball(346, 79, 0, 0, blue)); balls.push(new Ball(335, 84, 0, 0, blue)); balls.push(new Ball(330, 98, 0, 0, blue)); balls.push(new Ball(334, 111, 0, 0, blue)); balls.push(new Ball(348, 116, 0, 0, blue)); balls.push(new Ball(362, 109, 0, 0, blue)); balls.push(new Ball(362, 94, 0, 0, blue)); balls.push(new Ball(355, 128, 0, 0, blue)); balls.push(new Ball(340, 135, 0, 0, blue)); balls.push(new Ball(327, 142, 0, 0, blue)); balls.push(new Ball(325, 155, 0, 0, blue)); balls.push(new Ball(339, 165, 0, 0, blue)); balls.push(new Ball(352, 166, 0, 0, blue)); balls.push(new Ball(367, 161, 0, 0, blue)); balls.push(new Ball(371, 149, 0, 0, blue)); balls.push(new Ball(366, 137, 0, 0, blue)); // L balls.push(new Ball(394, 49, 0, 0, green)); balls.push(new Ball(381, 50, 0, 0, green)); balls.push(new Ball(391, 61, 0, 0, green)); balls.push(new Ball(390, 73, 0, 0, green)); balls.push(new Ball(392, 89, 0, 0, green)); balls.push(new Ball(390, 105, 0, 0, green)); balls.push(new Ball(390, 118, 0, 0, green)); balls.push(new Ball(388, 128, 0, 0, green)); balls.push(new Ball(400, 128, 0, 0, green)); // E balls.push(new Ball(426, 101, 0, 0, red)); balls.push(new Ball(436, 98, 0, 0, red)); balls.push(new Ball(451, 95, 0, 0, red)); balls.push(new Ball(449, 83, 0, 0, red)); balls.push(new Ball(443, 78, 0, 0, red)); balls.push(new Ball(430, 77, 0, 0, red)); balls.push(new Ball(418, 82, 0, 0, red)); balls.push(new Ball(414, 93, 0, 0, red)); balls.push(new Ball(412, 108, 0, 0, red)); balls.push(new Ball(420, 120, 0, 0, red)); balls.push(new Ball(430, 127, 0, 0, red)); balls.push(new Ball(442, 130, 0, 0, red)); balls.push(new Ball(450, 125, 0, 0, red)); return balls; } function updateBalls(kin, balls){ var canvas = kin.getCanvas(); var context = kin.getContext(); var collisionDamper = 0.3; var floorFriction = 0.0005 * kin.getTimeInterval(); var mouseForceMultiplier = 1 * kin.getTimeInterval(); var restoreForce = 0.002 * kin.getTimeInterval(); for (var n = 0; n < balls.length; n++) { var ball = balls[n]; // set ball position based on velocity ball.y += ball.vy; ball.x += ball.vx; // restore forces if (ball.x > ball.origX) { ball.vx -= restoreForce; } else { ball.vx += restoreForce; } if (ball.y > ball.origY) { ball.vy -= restoreForce; } else { ball.vy += restoreForce; } // mouse forces var mousePos = kin.getMousePos(); mouseX = mousePos === null ? 99999 : mousePos.x; mouseY = mousePos === null ? 99999 : mousePos.y; var distX = ball.x - mouseX; var distY = ball.y - mouseY; var radius = Math.sqrt(Math.pow(distX, 2) + Math.pow(distY, 2)); var totalDist = Math.abs(distX) + Math.abs(distY); var forceX = (Math.abs(distX) / totalDist) * (1 / radius) * mouseForceMultiplier; var forceY = (Math.abs(distY) / totalDist) * (1 / radius) * mouseForceMultiplier; if (distX > 0) { // mouse is left of ball ball.vx += forceX; } else { ball.vx -= forceX; } if (distY > 0) { // mouse is on top of ball ball.vy += forceY; } else { ball.vy -= forceY; } // floor friction if (ball.vx > 0) { ball.vx -= floorFriction; } else if (ball.vx < 0) { ball.vx += floorFriction; } if (ball.vy > 0) { ball.vy -= floorFriction; } else if (ball.vy < 0) { ball.vy += floorFriction; } // floor condition if (ball.y > (canvas.height - ball.radius)) { ball.y = canvas.height - ball.radius - 2; ball.vy *= -1; ball.vy *= (1 - collisionDamper); } // ceiling condition if (ball.y < (ball.radius)) { ball.y = ball.radius + 2; ball.vy *= -1; ball.vy *= (1 - collisionDamper); } // right wall condition if (ball.x > (canvas.width - ball.radius)) { ball.x = canvas.width - ball.radius - 2; ball.vx *= -1; ball.vx *= (1 - collisionDamper); } // left wall condition if (ball.x < (ball.radius)) { ball.x = ball.radius + 2; ball.vx *= -1; ball.vx *= (1 - collisionDamper); } } } function Ball(x, y, vx, vy, color){ this.x = x; this.y = y; this.vx = vx; this.vy = vy; this.color = color; this.origX = x; this.origY = y; this.radius = 10; } window.onload = function(){ kin = new Kinetic_2d("myCanvas"); var canvas = kin.getCanvas(); var context = kin.getContext(); var mouseX = 99999; var mouseY = 99999; canvas.onmouseout = function(){ mouseX = 99999; mouseY = 99999; }; var balls = initBalls(); kin.setDrawStage(function(){ updateBalls(this, balls); this.clear(); var mousePos = kin.getMousePos(); mouseX = mousePos === null ? 99999 : mousePos.x; mouseY = mousePos === null ? 99999 : mousePos.y; for (var n = 0; n < balls.length; n++) { var ball = balls[n]; context.beginPath(); context.arc(ball.x, ball.y, ball.radius, 0, 2 * Math.PI, false); context.fillStyle = ball.color; context.fill(); } }); kin.startAnimation(); }; </script> </head> <body onmousedown="return false;"> <canvas id="myCanvas" width="578" height="200"> </canvas> </body> </html> |
Added nacl/demo/c.natcl.
> > | 1 2 | printf "I'm c.natcl" |
Added nacl/demo/canv.natcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 | # # crude canvas emulation for NaTcl -- mapping to HTML5 canvas # set ::canv_verbose 0 set ::canv_uniq 1 set ::canv_hooked 0 set ::canv_tlist {} set ::canv_jcnt 0 set ::canv_status_func 0 set ::canv_status_coords 0 # canv_status_coords : 1: some old items moved # canv_status_func: 0:unchanged 1:new-items-on-top 2:changed proc canv_addhook {} { if {$::canv_hooked} return set ::canv_hooked 1 ::nacl hook canv_hook } proc canv_new_items {} { return [lrange $::canv_tlist $::canv_jcnt end] } proc canv_compile_repaint l { set j "" set oldprep "" foreach i $l { set prep $::canv_jprep($i) if {[string compare $prep $oldprep]} { set oldprep $prep append j $prep } append j $::canv_jdraw($i) } return $j } proc canv_hook {} { set ::canv_hooked 0 set repaint 0 if {$::canv_status_coords} { set repaint 1 } if {![info exists ::canv_jcode]} { set ::canv_status_func 2 } switch $::canv_status_func { 0 { # valid, do nothing } 1 { # incremental, append set jnew [canv_compile_repaint [canv_new_items]] append ::canv_jcode $jnew append js "repaint = function(){\n$::canv_jcode\n}\n" if {!$repaint} { # old ones didn't move: just draw the new ones append js $jnew } set ::canv_jcnt [llength $::canv_tlist] } 2 { # invalid, recompute set ::canv_jcode "context.clearRect(0,0,canvas.width,canvas.height); \n" append ::canv_jcode [canv_compile_repaint $::canv_tlist] append js "repaint=function(){\n$::canv_jcode\n}\n" set ::canv_jcnt [llength $::canv_tlist] set repaint 1 } } set l {} foreach i [array names ::canv_moved] { #append js "canvcoords\[$i\]=\[[join $::canv_coords($i) ,]\];\n" lappend l "$i,\[[join $::canv_coords($i) ,]\]" } append js "updateCoords(\[[join $l ,]\]);\n" if {$repaint} { append js "repaint();\n" } set ::canv_status_func 0 set ::canv_status_coords 0 array unset ::canv_moved if {[info exists js]} { if {$::canv_verbose} { printf "CANV_HOOK emits:\n$js\n" } nacl js $js } } proc lremove {l e} { set out {} foreach x $l { if {$x==$e} continue lappend out $x } return $out } proc canv_delete id { if {$id=="all"} { array unset ::canv_moved array unset ::canv_coords array unset ::canv_jprep array unset ::canv_jdraw set ::canv_tlist {} set ::canv_status_func 2 } else { catch {unset ::canv_moved($id)} unset ::canv_coords($id) unset ::canv_jprep($id) unset ::canv_jdraw($id) set ::canv_tlist [lremove $::canv_tlist $id] set ::canv_status_func 2 } canv_addhook } proc canv_find tag { if {$tag!="all"} { error "Unsupported tag '$tag'" } return $::canv_tlist } proc canv_create {ty args} { set id $::canv_uniq incr ::canv_uniq lappend ::canv_tlist $id set att(-fill) "#FFFFFF" set att(-outline) "#000000" switch -exact -- $ty { rect { foreach {x1 y1 x2 y2} $args break set ::canv_coords($id) [list $x1 $y1 [expr {$x2-$x1}] [expr {$y2-$y1}]] array set att [lrange $args 4 end] set prep "" set draw "" if {$att(-outline)!=""} {append prep "context.strokeStyle='$att(-outline)';";append draw "context.stroke();"} if {$att(-fill)!=""} {append prep "context.fillStyle='$att(-fill)';";append draw "context.fill();"} set ::canv_jprep($id) $prep set ::canv_jdraw($id) "context.beginPath();context.rect(canvcoords\[$id\]\[0\],canvcoords\[$id\]\[1\],canvcoords\[$id\]\[2\],canvcoords\[$id\]\[3\]);$draw\n" } circle { set ::canv_coords($id) [lrange $args 0 2] array set att [lrange $args 3 end] set prep "" set draw "" if {$att(-outline)!=""} {append prep "context.strokeStyle='$att(-outline)';";append draw "context.stroke();"} if {$att(-fill)!=""} {append prep "context.fillStyle='$att(-fill)';";append draw "context.fill();"} set ::canv_jprep($id) $prep set ::canv_jdraw($id) "context.beginPath();context.arc(canvcoords\[$id\]\[0\],canvcoords\[$id\]\[1\],canvcoords\[$id\]\[2\],0,2*Math.PI,0);$draw\n" } default {error "Unknown canv item type '$ty'"} } set ::canv_type($id) $ty if {!$::canv_status_func} { # incremental set ::canv_status_func 1 } set ::canv_moved($id) 1 canv_addhook return $id } proc canv_move {id dx dy} { foreach {x y} $::canv_coords($id) break incr x $dx incr y $dy set ::canv_coords($id) [concat [list $x $y] [lrange $::canv_coords($id) 2 end]] if {![info exists ::canv_moved($id)]} { set ::canv_moved($id) 1 set ::canv_status_coords 1 } } proc canv_moveto {id x y} { set ::canv_coords($id) [concat [list $x $y] [lrange $::canv_coords($id) 2 end]] if {![info exists ::canv_moved($id)]} { set ::canv_moved($id) 1 set ::canv_status_coords 1 } } proc canv_bind {evt cb} { switch -exact -- $evt { <Motion> { nacl js "canvas.onmousemove = function (evt) { tclDo([::nacl jsquote "$cb "]+(evt.clientX-canvas.offsetLeft)+' '+(evt.clientY-canvas.offsetTop)); }" } <Leave> { nacl js "canvas.onmouseout = function (evt) { tclDo([::nacl jsquote "$cb "]); }" } <Enter> { nacl js "canvas.onmouseover = function (evt) { tclDo([::nacl jsquote "$cb "]); }" } default {error "Unsupported event '$evt'"} } } |
Added nacl/demo/index.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 | <!DOCTYPE html> <html> <!-- Copyright (c) 2010 The Native Client Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. --> <head> <title>Tcl in Nacl</title> <script type="text/javascript"> tclModule = null; // Global application object. statusText = 'NO-STATUS'; function nil() {}; // Handle a message coming from the NaCl module. function handleMessage(message_event) { alert("Result: "+message_event.data); } function moduleDidLoad() { tclModule = document.getElementById('tcl'); tclModule.addEventListener('message', handleMessage, false); updateStatus('SUCCESS'); } // If the page loads before the Native Client module loads, then set the // status message indicating that the module is still loading. Otherwise, // do not change the status message. function pageDidLoad() { if (tclModule == null) { updateStatus('LOADING...'); } else { // It's possible that the Native Client module onload event fired // before the page's onload event. In this case, the status message // will reflect 'SUCCESS', but won't be displayed. This call will // display the current message. updateStatus(); } } function doeval() { try { tclModule.postMessage("eval:"+this.the_form.input_id.value); } catch(e) { alert(e.message); } } // Set the global status message. If the element with id 'statusField' // exists, then set its HTML to the status message as well. // opt_message The message test. If this is null or undefined, then // attempt to set the element with id 'statusField' to the value of // |statusText|. function updateStatus(opt_message) { if (opt_message) statusText = opt_message; var statusField = document.getElementById('status_field'); if (statusField) { statusField.innerHTML = statusText; } } </script> </head> <body onload="pageDidLoad()"> <h1>Native Client Tcl Module</h1> <p> <form name="the_form" action="javascript:doeval()"> <input type="text" id="input_id" name="inputbox" value="list a b c"><p> <input type="button" value="Call eval()" onclick="doeval()"> </form> <!-- Load the published .nexe. This includes the 'src' attribute which shows how to load multi-architecture modules. Each entry in the "nexes" object in the .nmf manifest file is a key-value pair: the key is the runtime ('x86-32', 'x86-64', etc.); the value is a URL for the desired NaCl module. To load the debug versions of your .nexes, set the 'src' attribute to the _dbg.nmf version of the manifest file. Note that the <EMBED> element is wrapped inside a <DIV>, which has a 'load' event listener attached. This method is used instead of attaching the 'load' event listener directly to the <EMBED> element to ensure that the listener is active before the NaCl module 'load' event fires. --> <div id="listener"> <script type="text/javascript"> document.getElementById('listener') .addEventListener('load', moduleDidLoad, true); </script> <embed name="nacl_module" id="tcl" width=0 height=0 src="tcl.nmf" type="application/x-nacl"/> </div> </p> <p>If the module is working correctly, a click on the "Call eval()" button should open a popup dialog containing the Tcl result as its value.</p> <h2>Status</h2> <div id="status_field">NO-STATUS</div> </body> </html> |
Added nacl/demo/inter.html.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <!DOCTYPE html> <html> <head> <script type="text/javascript" src="loader.js"></script> </head> <body> <div id="listener"> <script type="text/javascript"> document.getElementById('listener') .addEventListener('load', moduleDidLoad, true); </script> <textarea id="txt" cols="160" rows="40"></textarea> <embed name='nacl_module' id='tcl' width=0 height=0 src='../tcl.nmf' type='application/x-nacl' verbose=0 source='inter.natcl'> <h2>Status</h2> <div id="modstatus">NO-STATUS</div> </embed> </div> <p style="font-size : smaller;"> To run this demo, you need <ul style="font-size : smaller;"> <li> An x86-family processor</li> <li> Chrome 15 or higher</li> <li> Enabled "Native Client" item in about:flags</li> <li> if everything else fails, try the Nacl demos at <a href="http://code.google.com/chrome/nativeclient/docs/examples.html">http://code.google.com/chrome/nativeclient/docs/examples.html</a></li> </ul> </p> </body> </html> |
Added nacl/demo/inter.natcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | # sourced by inter.html demo ::nacl::js { t0=document.getElementById('txt'); function bot(w) { len=w.value.length+1; w.setSelectionRange(len,len); w.focus(); } t0.value = "# Type Tcl code in there\n"; t0.onkeydown=function(event) { if (event.which==13) { bot(t0); tclDoCoro("swallow \""+tclEsc(t0.value.replace(/.*\n/g,''))+"\""); bot(t0); } return true; } bot(t0); } proc swallow s { append ::accu $s \n if {[info complete $::accu]} { set x $::accu unset ::accu set res [uplevel #0 $x] ::nacl::js "t0.value+=[::nacl::jsquote $res\n];bot(t0);" } } proc ::nacl::bgerror s { ::nacl::js "t0.value+=[::nacl::jsquote ###$s\n];bot(t0);" } source rowland.natcl |
Added nacl/demo/kinetic2d-v1.0.3.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 | /** * KineticJS 2d JavaScript Library v1.0.3 * http://www.kineticjs.com/ * Copyright 2011, Eric Rowell * Licensed under the MIT or GPL Version 2 licenses. * Date: September 2 2011 * * Copyright (C) 2011 by Eric Rowell * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ var Kinetic_2d = function(canvasId) { this.canvas = document.getElementById(canvasId); this.context = this.canvas.getContext("2d"); this.drawStage = undefined; this.listening = false; // desktop flags this.mousePos = null; this._mouseDown = false; this._mouseUp = false; this._mouseOver = false; this._mouseMove = false; // mobile flags this.touchPos = null; this._touchStart = false; this._touchMove = false; this._touchEnd = false; // Region Events this._currentRegion = null; this._regionIndex = 0; this._lastRegionIndex = -1; this._mouseOverRegionIndex = -1; // Animation this.t = 0; this.timeInterval = 0; this.startTime = 0; this.lastTime = 0; this.frame = 0; this.animating = false; this.mouseDown = false; // provided by Paul Irish window.requestAnimFrame = (function(callback) { return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 40); }; })(); }; // ======================================= GENERAL // ======================================= Kinetic_2d.prototype.getContext = function() { return this.context; }; Kinetic_2d.prototype.getCanvas = function() { return this.canvas; }; Kinetic_2d.prototype.clear = function() { this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); }; Kinetic_2d.prototype.getCanvasPos = function() { var obj = this.getCanvas(); var top = 0; var left = 0; while(obj.tagName != "BODY") { top += obj.offsetTop; left += obj.offsetLeft; obj = obj.offsetParent; } return { top : top, left : left }; }; Kinetic_2d.prototype._drawStage = function() { if(this.drawStage !== undefined) { this.drawStage(); // desktop flags this._mouseOver = false; this._mouseMove = false; this._mouseDown = false; this._mouseUp = false; // mobile touch flags this._touchStart = false; this._touchMove = false; this._touchEnd = false; } }; Kinetic_2d.prototype.setDrawStage = function(func) { this.drawStage = func; this.listen(); }; // ======================================= CANVAS EVENTS Kinetic_2d.prototype.handleEvent = function(evt) { if(!evt) { evt = window.event; } this.setMousePosition(evt); this.setTouchPosition(evt); this._regionIndex = 0; if(!this.animating) { this._drawStage(); } }; Kinetic_2d.prototype.listen = function() { var that = this; this._drawStage(); // desktop events this.canvas.addEventListener("mousedown", function(evt) { that._mouseDown = true; that.mouseDown = true; that.handleEvent(evt); }, false); this.canvas.addEventListener("mousemove", function(evt) { that.handleEvent(evt); }, false); this.canvas.addEventListener("mouseup", function(evt) { that._mouseUp = true; that.mouseDown = false; that.handleEvent(evt); }, false); this.canvas.addEventListener("mouseover", function(evt) { that.handleEvent(evt); }, false); this.canvas.addEventListener("mouseout", function(evt) { that.mousePos = null; }, false); // mobile events this.canvas.addEventListener("touchstart", function(evt) { evt.preventDefault(); that._touchStart = true; that.handleEvent(evt); }, false); this.canvas.addEventListener("touchmove", function(evt) { evt.preventDefault(); that.handleEvent(evt); }, false); this.canvas.addEventListener("touchend", function(evt) { evt.preventDefault(); that._touchEnd = true; that.handleEvent(evt); }, false); }; Kinetic_2d.prototype.getMousePos = function(evt) { return this.mousePos; }; Kinetic_2d.prototype.getTouchPos = function(evt) { return this.touchPos; }; Kinetic_2d.prototype.setMousePosition = function(evt) { var mouseX = evt.clientX - this.getCanvasPos().left + window.pageXOffset; var mouseY = evt.clientY - this.getCanvasPos().top + window.pageYOffset; this.mousePos = { x : mouseX, y : mouseY }; }; Kinetic_2d.prototype.setTouchPosition = function(evt) { if(evt.touches !== undefined && evt.touches.length == 1) { // Only deal with // one finger var touch = evt.touches[0]; // Get the information for finger #1 var touchX = touch.pageX - this.getCanvasPos().left + window.pageXOffset; var touchY = touch.pageY - this.getCanvasPos().top + window.pageYOffset; this.touchPos = { x : touchX, y : touchY }; } }; Kinetic_2d.prototype.isMouseDown = function() { return this.mouseDown; }; // ======================================= REGION EVENTS Kinetic_2d.prototype.beginRegion = function() { this._currentRegion = {}; this._regionIndex++; }; Kinetic_2d.prototype.addRegionEventListener = function(type, func) { var event = (type.indexOf('touch') == -1) ? 'on' + type : type; this._currentRegion[event] = func; }; Kinetic_2d.prototype.closeRegion = function() { var pos = this.touchPos || this.mousePos; if(pos !== null && this.context.isPointInPath(pos.x, pos.y)) { if(this._lastRegionIndex != this._regionIndex) { this._lastRegionIndex = this._regionIndex; } // handle onmousedown if(this._mouseDown && this._currentRegion.onmousedown !== undefined) { this._currentRegion.onmousedown(); this._mouseDown = false; } // handle onmouseup else if(this._mouseUp && this._currentRegion.onmouseup !== undefined) { this._currentRegion.onmouseup(); this._mouseUp = false; } // handle onmouseover else if(!this._mouseOver && this._regionIndex != this._mouseOverRegionIndex && this._currentRegion.onmouseover !== undefined) { this._currentRegion.onmouseover(); this._mouseOver = true; this._mouseOverRegionIndex = this._regionIndex; } // handle onmousemove else if(!this._mouseMove && this._currentRegion.onmousemove !== undefined) { this._currentRegion.onmousemove(); this._mouseMove = true; } // handle touchstart if(this._touchStart && this._currentRegion._touchStart !== undefined) { this._currentRegion._touchStart(); this._touchStart = false; } // handle touchend if(this._touchEnd && this._currentRegion._touchEnd !== undefined) { this._currentRegion._touchEnd(); this._touchEnd = false; } // handle touchmove if(!this._touchMove && this._currentRegion._touchMove !== undefined) { this._currentRegion._touchMove(); this._touchMove = true; } } else if(this._regionIndex == this._lastRegionIndex) { this._lastRegionIndex = -1; this._mouseOverRegionIndex = -1; // handle mouseout condition if(this._currentRegion.onmouseout !== undefined) { this._currentRegion.onmouseout(); } } }; // ======================================= ANIMATION // ======================================= Kinetic_2d.prototype.isAnimating = function() { return this.animating; }; Kinetic_2d.prototype.getFrame = function() { return this.frame; }; Kinetic_2d.prototype.startAnimation = function() { this.animating = true; var date = new Date(); this.startTime = date.getTime(); this.lastTime = this.startTime; this._drawStage(); this.animationLoop(); }; Kinetic_2d.prototype.stopAnimation = function() { this.animating = false; }; Kinetic_2d.prototype.getTimeInterval = function() { return this.timeInterval; }; Kinetic_2d.prototype.getTime = function() { return this.t; }; Kinetic_2d.prototype.getFps = function() { return this.timeInterval > 0 ? 1000 / this.timeInterval : 0; }; Kinetic_2d.prototype.animationLoop = function() { var that = this; this.frame++; var date = new Date(); var thisTime = date.getTime(); this.timeInterval = thisTime - this.lastTime; this.t += this.timeInterval; this.lastTime = thisTime; this._drawStage(); if(this.animating) { requestAnimFrame(function() { that.animationLoop(); }); } }; |
Added nacl/demo/loader.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 | // NaTcl -- JS glue var tclModule = null; // our singleton Tcl interp function printf() { // I like debugging to stderr instead of console.log, // because when things go wrong, the JS console is not // alays reachable. tclModule.postMessage('eval:printf '+Array.prototype.slice.call(arguments).join(' ')); } // --- tclDo is the main JS-Tcl trampoline. // // Its job is to pass a Tcl string to [eval] (through naclwrap, see // init.nacl), and then take back the result as JS and eval() it. // It also detects errors in the latter eval() and pipes them back // to [bgerror]. function tclEsc(text) { return text.replace(/([\[\]\\$""{}])/g,'\\$1'); } function tclDo(s) { //console.log("TclDo: "+s); tclModule.postMessage("eval:::nacl::wrap {" + s + "}"); } function tclDoCoro(s) { tclModule.postMessage("eval:coroutine ::main_coro ::nacl::wrap \"" + tclEsc(s) + "\""); } function tcl() { tclDo(Array.prototype.slice.call(arguments).join(" ")); } // Handle a message coming from the NaCl module. function handleMessage(message_event) { try { t = message_event.data; //console.log("JSdo:"+t); window.eval(t); } catch(err) { //printf("JS-err:"+err); alert("ERROR:"+err); } } function serialT (thing) { alert("serialT " + thing.type + " " + thing.toString()); var result = '{'; switch (thing.type) { case 'string': return tclEsc(thing); break; case 'array': for (var i=0; i < thing.length(); i++) { result = result + " " + serialT(thing[i]); } result = result + '}'; break; case 'object': for (var prop in thing) { result = result + " " + serialT(prop) + " " + serialT(thing[prop]); } result = result + '}'; break; case 'function': result = thing.toString(); break; default: return undefined; break; } return result; } function callback(to,js) { alert("callback " + to + " " + js); try { tclDo(to + " " + serialT(eval(js))); } catch (err) { alert("JS-error " + err); //printf("JS-err:", err); setTimeout('tcl("::nacl::bgerror,"'+ err + ',' + js + ')',0); } } // --- tclsource starts an XHR, and calls the given 'tcb' (Tcl // --- Callback) on completion. A catchable Tcl-level error is raised // --- in case of not-200. Used by [source]. function tclsource(url,tcb) { //printf('tclsource:'+url); xs = new XMLHttpRequest(); xs.open("GET",url,true); xs.send(null); xs.onreadystatechange = function() { //printf("XHR-source:"+xs.readyState); if (xs.readyState==4) { if (xs.status==200) { tclDo(tcb+" {"+xs.responseText+"}"); } else { tclDo(tcb+" {error \"Can't source -- "+xs.statusText+"\"}"); } } }; } // traverse - apply function to subtree of dom returning object function traverse(fn) { var result; var target; if (arguments.length() > 1) { target = arguments[1]; } else { target = document; } result[target]=fn.apply(target); for (var i=0; i<target.childNodes.length; i++) { var child = target.childNodes[i]; var traversal = traverse(fn, child); for (var prop in traversal) { result[prop] = traversal[prop]; } } return result; } // ---------- GUI and standard NaCl-loading machinery -------- function moduleDidLoad() { tclModule = document.getElementById('tcl'); tclModule.addEventListener('message', handleMessage, false); // tcl('lappend', '::JS', "alert('ARGV:[join $::argv]')"); tcl('eval', 'coroutine', '::main_coro', 'source', '[dict get $::argv source]'); } // runTclScripts - collect all <script> elements with type text/tcl // Pass them to the Tcl header given in 'where' (or uplevel) function runTclScripts(where) { if (where == undefined) { where = "uplevel #0"; } var scripts = document.getElementsByTagName('script'); var script = ""; for (var i = 0; i < scripts.length; i++) { if (scripts[i].getAttribute('type') == 'text/tcl') { if (scripts[i].hasAttribute('src')) { script = script + '\nsource ' + scripts[i].getAttribute('src'); } var s = scripts[i].innerHTML; if (s != "") { script = script + '\n' + s; } } } tclDo(where + " {" + tclEsc(script)+ "}"); } |
Added nacl/demo/rowland.natcl.
> > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | proc tcl::mathfunc::gcd {a b} { while {$b} {set b [expr {$a % [set a $b]}]} return $a } # Rowland's: compute a(n)-a(n-1) where a(1)=7 and # a(n) = a(n – 1) + gcd(n, a(n – 1)) proc rowland m { set a 7 set n 1 set out {} while {$n<=$m} { incr n set b $a set a [expr {$b+gcd($n,$b)}] set p [expr {$a-$b}] if {$p>1} {lappend out $p} } return $out } |
Added nacl/init.natcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 | #------ Standard NaTcl preamble namespace eval ::nacl { variable verbose 0 # core JS/Tcl interaction proc jsquote s { regsub -all {[''\\]} $s {\\&} s regsub -all \n $s {'+"\\n"+'} s return '${s}' } # hook - append Tcl hooks to be evaluated per ??? variable hooks {} proc hook {args} { variable hooks lappend hooks {*}$args } # js - append javascript to be evaluated in nacl # as a result of currently evaluating Tcl script variable JS {} ;# accumulation of javascript to evaluate proc js {args} { variable JS append JS [join $args \;\n] \n } variable defaults {} proc opts {args} { set type "" if {[llength $args]%2} { set args [lassign $args type] } set opts {} variable defaults if {$type ne "" && [dict exists $defaults $type]} { set args [list {*}[dict get $defaults $type] {*}$args] } dict for {n v} $args { if {$v eq ""} { set v "''" ;# ensure we don't send naked names } lappend opts "$n:$v" } if {$opts eq ""} { return "" } else { return "\{[join $opts ,]\}" } } proc alert {args} { js "alert([::nacl::jsquote [join $args]])" } proc bgerror {args} { printf "### BGERROR: [join $args]\n# [info errorstack]" js "alert([::nacl::jsquote [join $args]])" } proc wrap {s} { variable hooks if {[catch { uplevel #0 $s foreach x $hooks {uplevel #0 $x} } err eo]} { bgerror "$err ($eo)" } variable JS; set toJS $JS; set JS "" return $toJS } # evall - evaluate a list as a command # returns javascript to evaluate in nacl proc evall {args} { variable hooks if {[catch { uplevel #0 $args foreach x $hooks {uplevel #0 $x} } err eo]} { bgerror "$err ($eo)" } variable JS; set toJS $JS; set JS "" return $toJS } # start - natcl module has been loaded with the following args proc start {args} { set defaults { verbose 0 script script toplevel toplevel } set ::argv [dict merge $defaults $args] if {[dict exists $args verbose]} { variable verbose [dict get $args verbose] } } namespace export -clear * namespace ensemble create -subcommands {} } namespace eval ::dom { # Delayed DOM-setting through the tclDo() trampoline proc put {element inner} { nacl js "$element.innerHTML=[nacl jsquote $inner]" } # get - get element's innerHTML and pass it to callback proc get {element args} { if {![llength $args]} { set args [info coroutine] } nacl js "tcl('[join $args "', '"]', '{'+$element.innerHTML+'}')" } namespace export -clear * namespace ensemble create -subcommands {} } # Coro-based [source] necessary for bootstrapping proc ::source {url} { nacl js "tclsource([::nacl::jsquote $url],[::nacl::jsquote [info coroutine]])" set x [yield] uplevel #0 $x } # Async [after] using JS's setTimeout() proc ::after {ms script} { nacl js "setTimeout(function(){tclDo([::nacl::jsquote $script]);},$ms)" } # Async [every] using JS's setInterval() proc ::every {ms script} { nacl js "setInterval(function(){tclDo([::nacl::jsquote $script]);},$ms)" } # Delayed DOM-setting through the tclDo() trampoline proc ::domset {element inner} { nacl js "$element.innerHTML=[::nacl::jsquote $inner]" } proc tclInit {} { printf "### tclInit called" } |
Added nacl/naclMain.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 | #include <stdlib.h> #include <string.h> //#include <ppapi/c/dev/ppb_var_deprecated.h> //#include <ppapi/c/dev/ppp_class_deprecated.h> #include <ppapi/c/pp_errors.h> #include <ppapi/c/pp_module.h> #include <ppapi/c/pp_var.h> #include <ppapi/c/ppb.h> #include <ppapi/c/ppb_instance.h> #include <ppapi/c/ppb_messaging.h> #include <ppapi/c/ppb_var.h> #include <ppapi/c/ppp.h> #include <ppapi/c/ppp_instance.h> #include <ppapi/c/ppp_messaging.h> struct MessageInfo { PP_Instance instance; struct PP_Var message; }; static struct PPB_Messaging* messaging_interface = NULL; static struct PPB_Var* var_interface = NULL; static PP_Module module_id = 0; #include <errno.h> #include "tcl.h" #include "tclInt.h" static Tcl_Interp *interp = NULL; static int pid = 0; static int verbose = 0; const char *init_tcl_contents = "set ::tcl_library {/}\n" # include "init.tcl.c" ; static int PrintfObjCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "string"); return TCL_ERROR; } printf("NaTcl(%d): %s\n", pid, Tcl_GetString(objv[1])); return TCL_OK; } static Tcl_Interp *NewTcl(void) { Tcl_Interp *ii; printf("DBUG:TclInitSubsystems\n"); TclInitSubsystems(); printf("DBUG:TclpSetInitialEncodings\n"); TclpSetInitialEncodings(); { volatile int x; x=0; if (x) printf("NaTcl(%d): BUSYLOOP : break out by resetting the var (set $eax=0)\n",pid); while(x) {} } printf("DBUG:CreateInterp\n"); ii=Tcl_CreateInterp(); if (!ii) { printf("NaTcl(%d): Tcl CreateInterp Failed !!!\n",pid); return NULL; } printf("DBUG:Tcl_Init2\n"); if (Tcl_Eval(ii,init_tcl_contents)!=TCL_OK) { printf("NaTcl(%d): Tcl Init Failed: %s !!!\n",pid,Tcl_GetStringResult(ii)); return NULL; } Tcl_CreateObjCommand(ii,"printf",PrintfObjCmd,NULL,NULL); Tcl_LinkVar(ii, "::nacl::verbose", (char *)&verbose, TCL_LINK_INT); TclSetPreInitScript("proc ::tclInit {} {}"); return ii; } static const char *EvalTcl(const char *s) { if (!interp) return "No Tcl Interp!!!"; Tcl_Eval(interp,s); return Tcl_GetStringResult(interp); } /** * Returns a mutable C string contained in the @a var or NULL if @a var is not * string. This makes a copy of the string in the @ var and adds a NULL * terminator. Note that VarToUtf8() does not guarantee the NULL terminator on * the returned string. See the comments for VatToUtf8() in ppapi/c/ppb_var.h * for more info. The caller is responsible for freeing the returned memory. * @param[in] var PP_Var containing string. * @return a C string representation of @a var. * @note The caller is responsible for freeing the returned string. */ static char* VarToCStr(struct PP_Var var) { uint32_t len = 0; if (var_interface != NULL) { const char* var_c_str = var_interface->VarToUtf8(var, &len); if (len > 0) { char* c_str = (char*)malloc(len + 1); memcpy(c_str, var_c_str, len); c_str[len] = 0; return c_str; } } return NULL; } /** * Creates new string PP_Var from C string. The resulting object will be a * refcounted string object. It will be AddRef()ed for the caller. When the * caller is done with it, it should be Release()d. * @param[in] str C string to be converted to PP_Var * @return PP_Var containing string. */ static struct PP_Var StrToVar(const char* str) { if (NULL != var_interface) return var_interface->VarFromUtf8(module_id, str, strlen(str)); return PP_MakeUndefined(); } /** * A simple function that always returns 42. * @return always returns the integer 42 static struct PP_Var FortyTwo() { return PP_MakeInt32(42); } */ /** * Called when the NaCl module is instantiated on the web page. The identifier * of the new instance will be passed in as the first argument (this value is * generated by the browser and is an opaque handle). This is called for each * instantiation of the NaCl module, which is each time the <embed> tag for * this module is encountered. * * If this function reports a failure (by returning @a PP_FALSE), the NaCl * module will be deleted and DidDestroy will be called. * @param[in] instance The identifier of the new instance representing this * NaCl module. * @param[in] argc The number of arguments contained in @a argn and @a argv. * @param[in] argn An array of argument names. These argument names are * supplied in the <embed> tag, for example: * <embed id="nacl_module" dimensions="2"> * will produce two arguments, one named "id" and one named "dimensions". * @param[in] argv An array of argument values. These are the values of the * arguments listed in the <embed> tag. In the above example, there will * be two elements in this array, "nacl_module" and "2". The indices of * these values match the indices of the corresponding names in @a argn. * @return @a PP_TRUE on success. */ static PP_Bool Instance_DidCreate(PP_Instance instance, uint32_t argc, const char* argn[], const char* argv[]) { printf("NaTcl(%d): DBUG: Instance_DidCreate %x\n", getpid(), (unsigned int)instance); int i; Tcl_Obj *args[1+argc+argc]; args[0] = Tcl_NewStringObj("::nacl::start",-1); Tcl_IncrRefCount(args[0]); for (i = 0; i < argc; i++) { printf("NaTcl(%d): DBUG: Instance_DidCreate arg %s=%s\n", getpid(), argn[i], argv[i]); args[(2*i)+1] = Tcl_NewStringObj(argn[i], -1); Tcl_IncrRefCount(args[(2*i)+1]); args[(2*i)+2] = Tcl_NewStringObj(argv[i], -1); Tcl_IncrRefCount(args[(2*i)+2]); } Tcl_EvalObjv(interp, argc*2+1, args, 0); for (i = 0; i < (2*argc)+1; i++) { Tcl_DecrRefCount(args[i]); } printf("NaTcl(%d): Instance_DidCreate result: %s\n", pid, Tcl_GetStringResult(interp)); return PP_TRUE; } /** * Called when the NaCl module is destroyed. This will always be called, * even if DidCreate returned failure. This routine should deallocate any data * associated with the instance. * @param[in] instance The identifier of the instance representing this NaCl * module. */ static void Instance_DidDestroy(PP_Instance instance) { } /** * Called when the position, the size, or the clip rect of the element in the * browser that corresponds to this NaCl module has changed. * @param[in] instance The identifier of the instance representing this NaCl * module. * @param[in] position The location on the page of this NaCl module. This is * relative to the top left corner of the viewport, which changes as the * page is scrolled. * @param[in] clip The visible region of the NaCl module. This is relative to * the top left of the plugin's coordinate system (not the page). If the * plugin is invisible, @a clip will be (0, 0, 0, 0). */ static void Instance_DidChangeView(PP_Instance instance, const struct PP_Rect* position, const struct PP_Rect* clip) { } /** * Notification that the given NaCl module has gained or lost focus. * Having focus means that keyboard events will be sent to the NaCl module * represented by @a instance. A NaCl module's default condition is that it * will not have focus. * * Note: clicks on NaCl modules will give focus only if you handle the * click event. You signal if you handled it by returning @a true from * HandleInputEvent. Otherwise the browser will bubble the event and give * focus to the element on the page that actually did end up consuming it. * If you're not getting focus, check to make sure you're returning true from * the mouse click in HandleInputEvent. * @param[in] instance The identifier of the instance representing this NaCl * module. * @param[in] has_focus Indicates whether this NaCl module gained or lost * event focus. */ static void Instance_DidChangeFocus(PP_Instance instance, PP_Bool has_focus) { } /** * Handler that gets called after a full-frame module is instantiated based on * registered MIME types. This function is not called on NaCl modules. This * function is essentially a place-holder for the required function pointer in * the PPP_Instance structure. * @param[in] instance The identifier of the instance representing this NaCl * module. * @param[in] url_loader A PP_Resource an open PPB_URLLoader instance. * @return PP_FALSE. */ static PP_Bool Instance_HandleDocumentLoad(PP_Instance instance, PP_Resource url_loader) { /* NaCl modules do not need to handle the document load function. */ return PP_FALSE; } /** * Handler for messages coming in from the browser via postMessage. Extracts * the method call from @a message, parses it for method name and value, then * calls the appropriate function. * @param[in] instance The instance ID. * @param[in] message The contents, copied by value, of the message sent from * browser via postMessage. */ void Messaging_HandleMessage(PP_Instance instance, struct PP_Var var_message) { struct PP_Var v = PP_MakeUndefined(); const char *message = NULL; if (var_message.type != PP_VARTYPE_STRING) { /* Only handle string messages */ v = StrToVar("ERROR:Method+Arg from Javascript is not a string!"); goto post; } message = VarToCStr(var_message); if (message == NULL) { v = StrToVar("ERROR:Method+Arg from Javascript is empty!"); goto post; } if (strncmp(message, "eval:", 5) == 0) { const char* str = message+5; if (verbose) { printf("NaTcl(%d): EVAL of: %s\n",pid, str); } const char* res = EvalTcl(str); if (verbose) { printf("NaTcl(%d): EVAL result: %s\n",pid, res); } v = StrToVar(res); goto post; } else { v = StrToVar("Unknown method"); goto post; } post: if (message) free((void *)message); messaging_interface->PostMessage(instance, v); if (v.type == PP_VARTYPE_STRING) { var_interface->Release(v); } } /** * Entrypoints for the module. * Initialize instance interface and scriptable object class. * @param[in] a_module_id module ID * @param[in] get_browser pointer to PPB_GetInterface * @return PP_OK on success, any other value on failure. */ PP_EXPORT int32_t PPP_InitializeModule(PP_Module a_module_id, PPB_GetInterface get_browser) { pid = getpid(); module_id = a_module_id; messaging_interface = (struct PPB_Messaging*)(get_browser(PPB_MESSAGING_INTERFACE)); var_interface = (struct PPB_Var*)(get_browser(PPB_VAR_INTERFACE)); printf("NaTcl(%d): DBUG: PPP_InitializeModule\n",pid); interp = NewTcl(); if (!interp) return PP_ERROR_FAILED; return PP_OK; } /** * Returns an interface pointer for the interface of the given name, or NULL * if the interface is not supported. * @param[in] interface_name name of the interface * @return pointer to the interface */ PP_EXPORT const void* PPP_GetInterface(const char* interface_name) { printf("NaTcl(%d): DBUG: PPP_GetInterface '%s'\n", getpid(), (char *)interface_name); if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0) { static struct PPP_Instance itf = { &Instance_DidCreate, &Instance_DidDestroy, &Instance_DidChangeView, &Instance_DidChangeFocus, &Instance_HandleDocumentLoad, }; return &itf; } else if (strcmp(interface_name, PPP_MESSAGING_INTERFACE) == 0) { static struct PPP_Messaging itf = { &Messaging_HandleMessage }; return &itf; } return NULL; } /** * Called before the plugin module is unloaded. */ PP_EXPORT void PPP_ShutdownModule() { // if (interp) EndTcl(interp); } |
Added nacl/naclMissing.c.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 | /* * * naclMissing: "implement" all missing syscalls, library funcs and vars. * */ #include <stdio.h> #include <errno.h> #include <string.h> int timezone; /* emulated */ char * getwd (char *buf) { printf("*BADSYSCALL:getwd\n"); strcpy(buf,"/"); return "/"; } /* traced */ int access(const char *name, int mode) { printf("*BADSYSCALL:access(\"%s\",%d)\n",name,mode); // return 0; errno=ENOENT;return -1; } /* plugged */ int _execve (){printf("BADSYSCALL:_execve\n");errno=EINVAL;return -1;} int accept (){printf("BADSYSCALL:accept\n");errno=EINVAL;return -1;} //int access (){printf("BADSYSCALL:access\n");errno=EINVAL;return -1;} int bind (){printf("BADSYSCALL:bind\n");errno=EINVAL;return -1;} int chdir (){printf("BADSYSCALL:chdir\n");errno=EINVAL;return -1;} int chmod (){printf("BADSYSCALL:chmod\n");errno=EINVAL;return -1;} int chown (){printf("BADSYSCALL:chown\n");errno=EINVAL;return -1;} int connect (){printf("BADSYSCALL:connect\n");errno=EINVAL;return -1;} int dlclose (){printf("BADSYSCALL:dlclose\n");errno=EINVAL;return -1;} int dlerror (){printf("BADSYSCALL:dlerror\n");errno=EINVAL;return -1;} int dlopen (){printf("BADSYSCALL:dlopen\n");errno=EINVAL;return -1;} int dlsym (){printf("BADSYSCALL:dlsym\n");errno=EINVAL;return -1;} int dup2 (){printf("BADSYSCALL:\n");errno=EINVAL;return -1;} int fcntl (){printf("BADSYSCALL:fcntl\n");errno=EINVAL;return -1;} int fork (){printf("BADSYSCALL:fork\n");errno=EINVAL;return -1;} int freeaddrinfo (){printf("BADSYSCALL:freeaddrinfo\n");errno=EINVAL;return -1;} int ftruncate (){printf("BADSYSCALL:ftruncate\n");errno=EINVAL;return -1;} char * gai_strerror (){printf("BADSYSCALL:gai_strerror\n");errno=EINVAL;return NULL;} int getaddrinfo (){printf("BADSYSCALL:getaddrinfo\n");errno=EINVAL;return -1;} int geteuid (){printf("BADSYSCALL:geteuid\n");errno=EINVAL;return -1;} int getgrgid (){printf("BADSYSCALL:getgrgid\n");errno=EINVAL;return -1;} void * getgrnam (){printf("BADSYSCALL:getgrnam\n");errno=EINVAL;return NULL;} void * gethostbyaddr (){printf("BADSYSCALL:gethostbyaddr\n");errno=EINVAL;return NULL;} void * gethostbyname (){printf("BADSYSCALL:gethostbyname\n");errno=EINVAL;return NULL;} int gethostname (){printf("BADSYSCALL:gethostname\n");errno=EINVAL;return -1;} int getnameinfo (){printf("BADSYSCALL:getnameinfo\n");errno=EINVAL;return -1;} int getpeername (){printf("BADSYSCALL:getpeername\n");errno=EINVAL;return -1;} void * getpwnam (){printf("BADSYSCALL:getpwnam\n");errno=EINVAL;return NULL;} void * getpwuid (){printf("BADSYSCALL:getpwuid\n");errno=EINVAL;return NULL;} void * getservbyname (){printf("BADSYSCALL:getservbyname\n");errno=EINVAL;return NULL;} int getsockname (){printf("BADSYSCALL:getsockname\n");errno=EINVAL;return -1;} int getsockopt (){printf("BADSYSCALL:getsockopt\n");errno=EINVAL;return -1;} int getuid (){printf("BADSYSCALL:getuid\n");errno=EINVAL;return -1;} //void * getwd (){printf("BADSYSCALL:getwd\n");errno=EINVAL;return NULL;} void * inet_ntoa (){printf("BADSYSCALL:inet_ntoa\n");errno=EINVAL;return NULL;} int kill (){printf("BADSYSCALL:kill\n");errno=EINVAL;return -1;} int link (){printf("BADSYSCALL:link\n");errno=EINVAL;return -1;} int listen (){printf("BADSYSCALL:listen\n");errno=EINVAL;return -1;} int lstat (){printf("BADSYSCALL:lstat\n");errno=EINVAL;return -1;} int mkdir (){printf("BADSYSCALL:mkdir\n");errno=EINVAL;return -1;} int mkfifo (){printf("BADSYSCALL:mkfifo\n");errno=EINVAL;return -1;} int mknod (){printf("BADSYSCALL:mknod\n");errno=EINVAL;return -1;} int pipe (){printf("BADSYSCALL:pipe\n");errno=EINVAL;return -1;} int readlink (){printf("BADSYSCALL:readlink\n");errno=EINVAL;return -1;} int recv (){printf("BADSYSCALL:recv\n");errno=EINVAL;return -1;} int rmdir (){printf("BADSYSCALL:rmdir\n");errno=EINVAL;return -1;} int select (){printf("BADSYSCALL:select\n");errno=EINVAL;return -1;} int send (){printf("BADSYSCALL:send\n");errno=EINVAL;return -1;} int setsockopt (){printf("BADSYSCALL:setsockopt\n");errno=EINVAL;return -1;} int shutdown (){printf("BADSYSCALL:shutdown\n");errno=EINVAL;return -1;} int socket (){printf("BADSYSCALL:socket\n");errno=EINVAL;return -1;} int symlink (){printf("BADSYSCALL:symlink\n");errno=EINVAL;return -1;} int umask (){printf("BADSYSCALL:umask\n");errno=EINVAL;return -1;} int unlink (){printf("BADSYSCALL:unlink\n");errno=EINVAL;return -1;} int utime (){printf("BADSYSCALL:utime\n");errno=EINVAL;return -1;} int waitpid (){printf("BADSYSCALL:waitpid\n");errno=EINVAL;return -1;} |
Added nacl/naclcompat.h.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 | typedef __signed__ char __s8; typedef unsigned char __u8; typedef __signed__ short __s16; typedef unsigned short __u16; typedef __signed__ int __s32; typedef unsigned int __u32; typedef __signed__ long __s64; typedef unsigned long __u64; #define __bitwise typedef __u16 __bitwise __le16; typedef __u16 __bitwise __be16; typedef __u32 __bitwise __le32; typedef __u32 __bitwise __be32; typedef __u64 __bitwise __le64; typedef __u64 __bitwise __be64; typedef __u16 __bitwise __sum16; typedef __u32 __bitwise __wsum; /* Description of data base entry for a single service. */ struct servent { char *s_name; /* Official service name. */ char **s_aliases; /* Alias list. */ int s_port; /* Port number. */ char *s_proto; /* Protocol to use. */ }; /* For setsockopt(2) */ #define SOL_SOCKET 1 #define SO_DEBUG 1 #define SO_REUSEADDR 2 #define SO_TYPE 3 #define SO_ERROR 4 #define SO_DONTROUTE 5 #define SO_BROADCAST 6 #define SO_SNDBUF 7 #define SO_RCVBUF 8 #define SO_SNDBUFFORCE 32 #define SO_RCVBUFFORCE 33 #define SO_KEEPALIVE 9 #define SO_OOBINLINE 10 #define SO_NO_CHECK 11 #define SO_PRIORITY 12 #define SO_LINGER 13 #define SO_BSDCOMPAT 14 /* To add :#define SO_REUSEPORT 15 */ #ifndef SO_PASSCRED /* powerpc only differs in these */ #define SO_PASSCRED 16 #define SO_PEERCRED 17 #define SO_RCVLOWAT 18 #define SO_SNDLOWAT 19 #define SO_RCVTIMEO 20 #define SO_SNDTIMEO 21 #endif /* Security levels - as per NRL IPv6 - don't actually do anything */ #define SO_SECURITY_AUTHENTICATION 22 #define SO_SECURITY_ENCRYPTION_TRANSPORT 23 #define SO_SECURITY_ENCRYPTION_NETWORK 24 #define SO_BINDTODEVICE 25 /* Socket filtering */ #define SO_ATTACH_FILTER 26 #define SO_DETACH_FILTER 27 #define SO_PEERNAME 28 #define SO_TIMESTAMP 29 #define SCM_TIMESTAMP SO_TIMESTAMP #define SO_ACCEPTCONN 30 #define SO_PEERSEC 31 #define SO_PASSSEC 34 #define SO_TIMESTAMPNS 35 #define SCM_TIMESTAMPNS SO_TIMESTAMPNS #define SO_MARK 36 #define SO_TIMESTAMPING 37 #define SCM_TIMESTAMPING SO_TIMESTAMPING #define SO_PROTOCOL 38 #define SO_DOMAIN 39 typedef socklen_t __socklen_t; struct addrinfo { int ai_flags; /* Input flags. */ int ai_family; /* Protocol family for socket. */ int ai_socktype; /* Socket type. */ int ai_protocol; /* Protocol for socket. */ socklen_t ai_addrlen; /* Length of socket address. */ struct sockaddr *ai_addr; /* Socket address for socket. */ char *ai_canonname; /* Canonical name for service location. */ struct addrinfo *ai_next; /* Pointer to next in list. */ }; /* Types of sockets. */ enum __socket_type { SOCK_STREAM = 1, /* Sequenced, reliable, connection-based byte streams. */ #define SOCK_STREAM SOCK_STREAM SOCK_DGRAM = 2, /* Connectionless, unreliable datagrams of fixed maximum length. */ #define SOCK_DGRAM SOCK_DGRAM SOCK_RAW = 3, /* Raw protocol interface. */ #define SOCK_RAW SOCK_RAW SOCK_RDM = 4, /* Reliably-delivered messages. */ #define SOCK_RDM SOCK_RDM SOCK_SEQPACKET = 5, /* Sequenced, reliable, connection-based, datagrams of fixed maximum length. */ #define SOCK_SEQPACKET SOCK_SEQPACKET SOCK_DCCP = 6, /* Datagram Congestion Control Protocol. */ #define SOCK_DCCP SOCK_DCCP SOCK_PACKET = 10, /* Linux specific way of getting packets at the dev level. For writing rarp and other similar things on the user level. */ #define SOCK_PACKET SOCK_PACKET /* Flags to be ORed into the type parameter of socket and socketpair and used for the flags parameter of paccept. */ SOCK_CLOEXEC = 02000000, /* Atomically set close-on-exec flag for the new descriptor(s). */ #define SOCK_CLOEXEC SOCK_CLOEXEC SOCK_NONBLOCK = 04000 /* Atomically mark descriptor(s) as non-blocking. */ #define SOCK_NONBLOCK SOCK_NONBLOCK }; /* Protocol families. */ #define PF_UNSPEC 0 /* Unspecified. */ #define PF_LOCAL 1 /* Local to host (pipes and file-domain). */ #define PF_UNIX PF_LOCAL /* POSIX name for PF_LOCAL. */ #define PF_FILE PF_LOCAL /* Another non-standard name for PF_LOCAL. */ #define PF_INET 2 /* IP protocol family. */ #define PF_AX25 3 /* Amateur Radio AX.25. */ #define PF_IPX 4 /* Novell Internet Protocol. */ #define PF_APPLETALK 5 /* Appletalk DDP. */ #define PF_NETROM 6 /* Amateur radio NetROM. */ #define PF_BRIDGE 7 /* Multiprotocol bridge. */ #define PF_ATMPVC 8 /* ATM PVCs. */ #define PF_X25 9 /* Reserved for X.25 project. */ #define PF_INET6 10 /* IP version 6. */ #define PF_ROSE 11 /* Amateur Radio X.25 PLP. */ #define PF_DECnet 12 /* Reserved for DECnet project. */ #define PF_NETBEUI 13 /* Reserved for 802.2LLC project. */ #define PF_SECURITY 14 /* Security callback pseudo AF. */ #define PF_KEY 15 /* PF_KEY key management API. */ #define PF_NETLINK 16 #define PF_ROUTE PF_NETLINK /* Alias to emulate 4.4BSD. */ #define PF_PACKET 17 /* Packet family. */ #define PF_ASH 18 /* Ash. */ #define PF_ECONET 19 /* Acorn Econet. */ #define PF_ATMSVC 20 /* ATM SVCs. */ #define PF_RDS 21 /* RDS sockets. */ #define PF_SNA 22 /* Linux SNA Project */ #define PF_IRDA 23 /* IRDA sockets. */ #define PF_PPPOX 24 /* PPPoX sockets. */ #define PF_WANPIPE 25 /* Wanpipe API sockets. */ #define PF_LLC 26 /* Linux LLC. */ #define PF_CAN 29 /* Controller Area Network. */ #define PF_TIPC 30 /* TIPC sockets. */ #define PF_BLUETOOTH 31 /* Bluetooth sockets. */ #define PF_IUCV 32 /* IUCV sockets. */ #define PF_RXRPC 33 /* RxRPC sockets. */ #define PF_ISDN 34 /* mISDN sockets. */ #define PF_PHONET 35 /* Phonet sockets. */ #define PF_IEEE802154 36 /* IEEE 802.15.4 sockets. */ #define PF_MAX 37 /* For now.. */ /* Address families. */ #define AF_UNSPEC PF_UNSPEC #define AF_LOCAL PF_LOCAL #define AF_UNIX PF_UNIX #define AF_FILE PF_FILE #define AF_INET PF_INET #define AF_AX25 PF_AX25 #define AF_IPX PF_IPX #define AF_APPLETALK PF_APPLETALK #define AF_NETROM PF_NETROM #define AF_BRIDGE PF_BRIDGE #define AF_ATMPVC PF_ATMPVC #define AF_X25 PF_X25 #define AF_INET6 PF_INET6 #define AF_ROSE PF_ROSE #define AF_DECnet PF_DECnet #define AF_NETBEUI PF_NETBEUI #define AF_SECURITY PF_SECURITY #define AF_KEY PF_KEY #define AF_NETLINK PF_NETLINK #define AF_ROUTE PF_ROUTE #define AF_PACKET PF_PACKET #define AF_ASH PF_ASH #define AF_ECONET PF_ECONET #define AF_ATMSVC PF_ATMSVC #define AF_RDS PF_RDS #define AF_SNA PF_SNA #define AF_IRDA PF_IRDA #define AF_PPPOX PF_PPPOX #define AF_WANPIPE PF_WANPIPE #define AF_LLC PF_LLC #define AF_CAN PF_CAN #define AF_TIPC PF_TIPC #define AF_BLUETOOTH PF_BLUETOOTH #define AF_IUCV PF_IUCV #define AF_RXRPC PF_RXRPC #define AF_ISDN PF_ISDN #define AF_PHONET PF_PHONET #define AF_IEEE802154 PF_IEEE802154 #define AF_MAX PF_MAX /* Socket level values. Others are defined in the appropriate headers. XXX These definitions also should go into the appropriate headers as far as they are available. */ #define SOL_RAW 255 #define SOL_DECNET 261 #define SOL_X25 262 #define SOL_PACKET 263 #define SOL_ATM 264 /* ATM layer (cell level). */ #define SOL_AAL 265 /* ATM Adaption Layer (packet level). */ #define SOL_IRDA 266 /* Maximum queue length specifiable by listen. */ #define SOMAXCONN 128 /* POSIX.1g specifies this type name for the `sa_family' member. */ typedef unsigned short int sa_family_t; /* This macro is used to declare the initial common members of the data types used for socket addresses, `struct sockaddr', `struct sockaddr_in', `struct sockaddr_un', etc. */ #define __SOCKADDR_COMMON(sa_prefix) \ sa_family_t sa_prefix##family #define __SOCKADDR_COMMON_SIZE (sizeof (unsigned short int)) /* Structure describing a generic socket address. */ struct sockaddr { __SOCKADDR_COMMON (sa_); /* Common data: address family and length. */ char sa_data[14]; /* Address data. */ }; /* Structure large enough to hold any socket address (with the historical exception of AF_UNIX). We reserve 128 bytes. */ #define __ss_aligntype unsigned long int #define _SS_SIZE 128 #define _SS_PADSIZE (_SS_SIZE - (2 * sizeof (__ss_aligntype))) struct sockaddr_storage { __SOCKADDR_COMMON (ss_); /* Address family, etc. */ __ss_aligntype __ss_align; /* Force desired alignment. */ char __ss_padding[_SS_PADSIZE]; }; /* Bits in the FLAGS argument to `send', `recv', et al. */ enum { MSG_OOB = 0x01, /* Process out-of-band data. */ #define MSG_OOB MSG_OOB MSG_PEEK = 0x02, /* Peek at incoming messages. */ #define MSG_PEEK MSG_PEEK MSG_DONTROUTE = 0x04, /* Don't use local routing. */ #define MSG_DONTROUTE MSG_DONTROUTE #ifdef __USE_GNU /* DECnet uses a different name. */ MSG_TRYHARD = MSG_DONTROUTE, # define MSG_TRYHARD MSG_DONTROUTE #endif MSG_CTRUNC = 0x08, /* Control data lost before delivery. */ #define MSG_CTRUNC MSG_CTRUNC MSG_PROXY = 0x10, /* Supply or ask second address. */ #define MSG_PROXY MSG_PROXY MSG_TRUNC = 0x20, #define MSG_TRUNC MSG_TRUNC MSG_DONTWAIT = 0x40, /* Nonblocking IO. */ #define MSG_DONTWAIT MSG_DONTWAIT MSG_EOR = 0x80, /* End of record. */ #define MSG_EOR MSG_EOR MSG_WAITALL = 0x100, /* Wait for a full request. */ #define MSG_WAITALL MSG_WAITALL MSG_FIN = 0x200, #define MSG_FIN MSG_FIN MSG_SYN = 0x400, #define MSG_SYN MSG_SYN MSG_CONFIRM = 0x800, /* Confirm path validity. */ #define MSG_CONFIRM MSG_CONFIRM MSG_RST = 0x1000, #define MSG_RST MSG_RST MSG_ERRQUEUE = 0x2000, /* Fetch message from error queue. */ #define MSG_ERRQUEUE MSG_ERRQUEUE MSG_NOSIGNAL = 0x4000, /* Do not generate SIGPIPE. */ #define MSG_NOSIGNAL MSG_NOSIGNAL MSG_MORE = 0x8000, /* Sender will send more. */ #define MSG_MORE MSG_MORE MSG_CMSG_CLOEXEC = 0x40000000 /* Set close_on_exit for file descriptor received through SCM_RIGHTS. */ #define MSG_CMSG_CLOEXEC MSG_CMSG_CLOEXEC }; /* Structure describing messages sent by `sendmsg' and received by `recvmsg'. */ struct msghdr { void *msg_name; /* Address to send to/receive from. */ socklen_t msg_namelen; /* Length of address data. */ struct iovec *msg_iov; /* Vector of data to send/receive into. */ size_t msg_iovlen; /* Number of elements in the vector. */ void *msg_control; /* Ancillary data (eg BSD filedesc passing). */ size_t msg_controllen; /* Ancillary data buffer length. !! The type should be socklen_t but the definition of the kernel is incompatible with this. */ int msg_flags; /* Flags on received message. */ }; # define __flexarr [] /* Structure used for storage of ancillary data object information. */ struct cmsghdr { size_t cmsg_len; /* Length of data in cmsg_data plus length of cmsghdr structure. !! The type should be socklen_t but the definition of the kernel is incompatible with this. */ int cmsg_level; /* Originating protocol. */ int cmsg_type; /* Protocol specific type. */ #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L __extension__ unsigned char __cmsg_data __flexarr; /* Ancillary data. */ #endif }; /* Ancillary data object manipulation macros. */ #if (!defined __STRICT_ANSI__ && __GNUC__ >= 2) || __STDC_VERSION__ >= 199901L # define CMSG_DATA(cmsg) ((cmsg)->__cmsg_data) #else # define CMSG_DATA(cmsg) ((unsigned char *) ((struct cmsghdr *) (cmsg) + 1)) #endif #define CMSG_NXTHDR(mhdr, cmsg) __cmsg_nxthdr (mhdr, cmsg) #define CMSG_FIRSTHDR(mhdr) \ ((size_t) (mhdr)->msg_controllen >= sizeof (struct cmsghdr) \ ? (struct cmsghdr *) (mhdr)->msg_control : (struct cmsghdr *) 0) #define CMSG_ALIGN(len) (((len) + sizeof (size_t) - 1) \ & (size_t) ~(sizeof (size_t) - 1)) #define CMSG_SPACE(len) (CMSG_ALIGN (len) \ + CMSG_ALIGN (sizeof (struct cmsghdr))) #define CMSG_LEN(len) (CMSG_ALIGN (sizeof (struct cmsghdr)) + (len)) # define __THROW extern struct cmsghdr *__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg) __THROW; #ifdef __USE_EXTERN_INLINES # ifndef _EXTERN_INLINE # define _EXTERN_INLINE __extern_inline # endif _EXTERN_INLINE struct cmsghdr * __NTH (__cmsg_nxthdr (struct msghdr *__mhdr, struct cmsghdr *__cmsg)) { if ((size_t) __cmsg->cmsg_len < sizeof (struct cmsghdr)) /* The kernel header does this so there may be a reason. */ return 0; __cmsg = (struct cmsghdr *) ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len)); if ((unsigned char *) (__cmsg + 1) > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen) || ((unsigned char *) __cmsg + CMSG_ALIGN (__cmsg->cmsg_len) > ((unsigned char *) __mhdr->msg_control + __mhdr->msg_controllen))) /* No more entries. */ return 0; return __cmsg; } #endif /* Use `extern inline'. */ /* Socket level message types. This must match the definitions in <linux/socket.h>. */ enum { SCM_RIGHTS = 0x01 /* Transfer file descriptors. */ #define SCM_RIGHTS SCM_RIGHTS #ifdef __USE_GNU , SCM_CREDENTIALS = 0x02 /* Credentials passing. */ # define SCM_CREDENTIALS SCM_CREDENTIALS #endif }; #ifdef __USE_GNU /* User visible structure for SCM_CREDENTIALS message */ struct ucred { pid_t pid; /* PID of sending process. */ uid_t uid; /* UID of sending process. */ gid_t gid; /* GID of sending process. */ }; #endif /* Ugly workaround for unclean kernel headers. */ #if !defined __USE_MISC && !defined __USE_GNU # ifndef FIOGETOWN # define __SYS_SOCKET_H_undef_FIOGETOWN # endif # ifndef FIOSETOWN # define __SYS_SOCKET_H_undef_FIOSETOWN # endif # ifndef SIOCATMARK # define __SYS_SOCKET_H_undef_SIOCATMARK # endif # ifndef SIOCGPGRP # define __SYS_SOCKET_H_undef_SIOCGPGRP # endif # ifndef SIOCGSTAMP # define __SYS_SOCKET_H_undef_SIOCGSTAMP # endif # ifndef SIOCGSTAMPNS # define __SYS_SOCKET_H_undef_SIOCGSTAMPNS # endif # ifndef SIOCSPGRP # define __SYS_SOCKET_H_undef_SIOCSPGRP # endif #endif /* Get socket manipulation related informations from kernel headers. */ #if !defined __USE_MISC && !defined __USE_GNU # ifdef __SYS_SOCKET_H_undef_FIOGETOWN # undef __SYS_SOCKET_H_undef_FIOGETOWN # undef FIOGETOWN # endif # ifdef __SYS_SOCKET_H_undef_FIOSETOWN # undef __SYS_SOCKET_H_undef_FIOSETOWN # undef FIOSETOWN # endif # ifdef __SYS_SOCKET_H_undef_SIOCATMARK # undef __SYS_SOCKET_H_undef_SIOCATMARK # undef SIOCATMARK # endif # ifdef __SYS_SOCKET_H_undef_SIOCGPGRP # undef __SYS_SOCKET_H_undef_SIOCGPGRP # undef SIOCGPGRP # endif # ifdef __SYS_SOCKET_H_undef_SIOCGSTAMP # undef __SYS_SOCKET_H_undef_SIOCGSTAMP # undef SIOCGSTAMP # endif # ifdef __SYS_SOCKET_H_undef_SIOCGSTAMPNS # undef __SYS_SOCKET_H_undef_SIOCGSTAMPNS # undef SIOCGSTAMPNS # endif # ifdef __SYS_SOCKET_H_undef_SIOCSPGRP # undef __SYS_SOCKET_H_undef_SIOCSPGRP # undef SIOCSPGRP # endif #endif /* Structure used to manipulate the SO_LINGER option. */ struct linger { int l_onoff; /* Nonzero to linger on close. */ int l_linger; /* Time to linger. */ }; /* Standard well-defined IP protocols. */ enum { IPPROTO_IP = 0, /* Dummy protocol for TCP */ IPPROTO_ICMP = 1, /* Internet Control Message Protocol */ IPPROTO_IGMP = 2, /* Internet Group Management Protocol */ IPPROTO_IPIP = 4, /* IPIP tunnels (older KA9Q tunnels use 94) */ IPPROTO_TCP = 6, /* Transmission Control Protocol */ IPPROTO_EGP = 8, /* Exterior Gateway Protocol */ IPPROTO_PUP = 12, /* PUP protocol */ IPPROTO_UDP = 17, /* User Datagram Protocol */ IPPROTO_IDP = 22, /* XNS IDP protocol */ IPPROTO_DCCP = 33, /* Datagram Congestion Control Protocol */ IPPROTO_RSVP = 46, /* RSVP protocol */ IPPROTO_GRE = 47, /* Cisco GRE tunnels (rfc 1701,1702) */ IPPROTO_IPV6 = 41, /* IPv6-in-IPv4 tunnelling */ IPPROTO_ESP = 50, /* Encapsulation Security Payload protocol */ IPPROTO_AH = 51, /* Authentication Header protocol */ IPPROTO_BEETPH = 94, /* IP option pseudo header for BEET */ IPPROTO_PIM = 103, /* Protocol Independent Multicast */ IPPROTO_COMP = 108, /* Compression Header protocol */ IPPROTO_SCTP = 132, /* Stream Control Transport Protocol */ IPPROTO_UDPLITE = 136, /* UDP-Lite (RFC 3828) */ IPPROTO_RAW = 255, /* Raw IP packets */ IPPROTO_MAX }; /* Internet address. */ struct in_addr { __be32 s_addr; }; #define IP_TOS 1 #define IP_TTL 2 #define IP_HDRINCL 3 #define IP_OPTIONS 4 #define IP_ROUTER_ALERT 5 #define IP_RECVOPTS 6 #define IP_RETOPTS 7 #define IP_PKTINFO 8 #define IP_PKTOPTIONS 9 #define IP_MTU_DISCOVER 10 #define IP_RECVERR 11 #define IP_RECVTTL 12 #define IP_RECVTOS 13 #define IP_MTU 14 #define IP_FREEBIND 15 #define IP_IPSEC_POLICY 16 #define IP_XFRM_POLICY 17 #define IP_PASSSEC 18 #define IP_TRANSPARENT 19 /* BSD compatibility */ #define IP_RECVRETOPTS IP_RETOPTS /* TProxy original addresses */ #define IP_ORIGDSTADDR 20 #define IP_RECVORIGDSTADDR IP_ORIGDSTADDR /* IP_MTU_DISCOVER values */ #define IP_PMTUDISC_DONT 0 /* Never send DF frames */ #define IP_PMTUDISC_WANT 1 /* Use per route hints */ #define IP_PMTUDISC_DO 2 /* Always DF */ #define IP_PMTUDISC_PROBE 3 /* Ignore dst pmtu */ #define IP_MULTICAST_IF 32 #define IP_MULTICAST_TTL 33 #define IP_MULTICAST_LOOP 34 #define IP_ADD_MEMBERSHIP 35 #define IP_DROP_MEMBERSHIP 36 #define IP_UNBLOCK_SOURCE 37 #define IP_BLOCK_SOURCE 38 #define IP_ADD_SOURCE_MEMBERSHIP 39 #define IP_DROP_SOURCE_MEMBERSHIP 40 #define IP_MSFILTER 41 #define MCAST_JOIN_GROUP 42 #define MCAST_BLOCK_SOURCE 43 #define MCAST_UNBLOCK_SOURCE 44 #define MCAST_LEAVE_GROUP 45 #define MCAST_JOIN_SOURCE_GROUP 46 #define MCAST_LEAVE_SOURCE_GROUP 47 #define MCAST_MSFILTER 48 #define IP_MULTICAST_ALL 49 #define MCAST_EXCLUDE 0 #define MCAST_INCLUDE 1 /* These need to appear somewhere around here */ #define IP_DEFAULT_MULTICAST_TTL 1 #define IP_DEFAULT_MULTICAST_LOOP 1 /* * Desired design of maximum size and alignment (see RFC2553) */ #define _K_SS_MAXSIZE 128 /* Implementation specific max size */ #define _K_SS_ALIGNSIZE (__alignof__ (struct sockaddr *)) /* Implementation specific desired alignment */ struct __kernel_sockaddr_storage { unsigned short ss_family; /* address family */ /* Following field(s) are implementation specific */ char __data[_K_SS_MAXSIZE - sizeof(unsigned short)]; /* space to achieve desired size, */ /* _SS_MAXSIZE value minus size of ss_family */ } __attribute__ ((aligned(_K_SS_ALIGNSIZE))); /* force desired alignment */ /* Request struct for multicast socket ops */ struct ip_mreq { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_interface; /* local IP address of interface */ }; struct ip_mreqn { struct in_addr imr_multiaddr; /* IP multicast address of group */ struct in_addr imr_address; /* local IP address of interface */ int imr_ifindex; /* Interface index */ }; struct ip_mreq_source { __be32 imr_multiaddr; __be32 imr_interface; __be32 imr_sourceaddr; }; struct ip_msfilter { __be32 imsf_multiaddr; __be32 imsf_interface; __u32 imsf_fmode; __u32 imsf_numsrc; __be32 imsf_slist[1]; }; #define IP_MSFILTER_SIZE(numsrc) \ (sizeof(struct ip_msfilter) - sizeof(__u32) \ + (numsrc) * sizeof(__u32)) struct group_req { __u32 gr_interface; /* interface index */ struct __kernel_sockaddr_storage gr_group; /* group address */ }; struct group_source_req { __u32 gsr_interface; /* interface index */ struct __kernel_sockaddr_storage gsr_group; /* group address */ struct __kernel_sockaddr_storage gsr_source; /* source address */ }; struct group_filter { __u32 gf_interface; /* interface index */ struct __kernel_sockaddr_storage gf_group; /* multicast address */ __u32 gf_fmode; /* filter mode */ __u32 gf_numsrc; /* number of sources */ struct __kernel_sockaddr_storage gf_slist[1]; /* interface index */ }; #define GROUP_FILTER_SIZE(numsrc) \ (sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \ + (numsrc) * sizeof(struct __kernel_sockaddr_storage)) struct in_pktinfo { int ipi_ifindex; struct in_addr ipi_spec_dst; struct in_addr ipi_addr; }; /* Structure describing an Internet (IP) socket address. */ #define __SOCK_SIZE__ 16 /* sizeof(struct sockaddr) */ struct sockaddr_in { sa_family_t sin_family; /* Address family */ __be16 sin_port; /* Port number */ struct in_addr sin_addr; /* Internet address */ /* Pad to size of `struct sockaddr'. */ unsigned char __pad[__SOCK_SIZE__ - sizeof(short int) - sizeof(unsigned short int) - sizeof(struct in_addr)]; }; #define sin_zero __pad /* for BSD UNIX comp. -FvK */ /* * Definitions of the bits in an Internet address integer. * On subnets, host and network parts are found according * to the subnet mask, not these masks. */ #define IN_CLASSA(a) ((((long int) (a)) & 0x80000000) == 0) #define IN_CLASSA_NET 0xff000000 #define IN_CLASSA_NSHIFT 24 #define IN_CLASSA_HOST (0xffffffff & ~IN_CLASSA_NET) #define IN_CLASSA_MAX 128 #define IN_CLASSB(a) ((((long int) (a)) & 0xc0000000) == 0x80000000) #define IN_CLASSB_NET 0xffff0000 #define IN_CLASSB_NSHIFT 16 #define IN_CLASSB_HOST (0xffffffff & ~IN_CLASSB_NET) #define IN_CLASSB_MAX 65536 #define IN_CLASSC(a) ((((long int) (a)) & 0xe0000000) == 0xc0000000) #define IN_CLASSC_NET 0xffffff00 #define IN_CLASSC_NSHIFT 8 #define IN_CLASSC_HOST (0xffffffff & ~IN_CLASSC_NET) #define IN_CLASSD(a) ((((long int) (a)) & 0xf0000000) == 0xe0000000) #define IN_MULTICAST(a) IN_CLASSD(a) #define IN_MULTICAST_NET 0xF0000000 #define IN_EXPERIMENTAL(a) ((((long int) (a)) & 0xf0000000) == 0xf0000000) #define IN_BADCLASS(a) IN_EXPERIMENTAL((a)) /* Address to accept any incoming messages. */ #define INADDR_ANY ((unsigned long int) 0x00000000) /* Address to send to all hosts. */ #define INADDR_BROADCAST ((unsigned long int) 0xffffffff) /* Address indicating an error return. */ #define INADDR_NONE ((unsigned long int) 0xffffffff) /* Network number for local host loopback. */ #define IN_LOOPBACKNET 127 /* Address to loopback in software to local host. */ #define INADDR_LOOPBACK 0x7f000001 /* 127.0.0.1 */ #define IN_LOOPBACK(a) ((((long int) (a)) & 0xff000000) == 0x7f000000) /* Defines for Multicast INADDR */ #define INADDR_UNSPEC_GROUP 0xe0000000U /* 224.0.0.0 */ #define INADDR_ALLHOSTS_GROUP 0xe0000001U /* 224.0.0.1 */ #define INADDR_ALLRTRS_GROUP 0xe0000002U /* 224.0.0.2 */ #define INADDR_MAX_LOCAL_GROUP 0xe00000ffU /* 224.0.0.255 */ /* * IPv6 address structure */ struct in6_addr { union { __u8 u6_addr8[16]; __be16 u6_addr16[8]; __be32 u6_addr32[4]; } in6_u; #define s6_addr in6_u.u6_addr8 #define s6_addr16 in6_u.u6_addr16 #define s6_addr32 in6_u.u6_addr32 }; /* IPv6 Wildcard Address (::) and Loopback Address (::1) defined in RFC2553 * NOTE: Be aware the IN6ADDR_* constants and in6addr_* externals are defined * in network byte order, not in host byte order as are the IPv4 equivalents */ struct sockaddr_in6 { unsigned short int sin6_family; /* AF_INET6 */ __be16 sin6_port; /* Transport layer port # */ __be32 sin6_flowinfo; /* IPv6 flow information */ struct in6_addr sin6_addr; /* IPv6 address */ __u32 sin6_scope_id; /* scope id (new in RFC2553) */ }; struct ipv6_mreq { /* IPv6 multicast address of group */ struct in6_addr ipv6mr_multiaddr; /* local IPv6 address of interface */ int ipv6mr_ifindex; }; #define ipv6mr_acaddr ipv6mr_multiaddr struct in6_flowlabel_req { struct in6_addr flr_dst; __be32 flr_label; __u8 flr_action; __u8 flr_share; __u16 flr_flags; __u16 flr_expires; __u16 flr_linger; __u32 __flr_pad; /* Options in format of IPV6_PKTOPTIONS */ }; #define IPV6_FL_A_GET 0 #define IPV6_FL_A_PUT 1 #define IPV6_FL_A_RENEW 2 #define IPV6_FL_F_CREATE 1 #define IPV6_FL_F_EXCL 2 #define IPV6_FL_S_NONE 0 #define IPV6_FL_S_EXCL 1 #define IPV6_FL_S_PROCESS 2 #define IPV6_FL_S_USER 3 #define IPV6_FL_S_ANY 255 /* * Bitmask constant declarations to help applications select out the * flow label and priority fields. * * Note that this are in host byte order while the flowinfo field of * sockaddr_in6 is in network byte order. */ #define IPV6_FLOWINFO_FLOWLABEL 0x000fffff #define IPV6_FLOWINFO_PRIORITY 0x0ff00000 /* These defintions are obsolete */ #define IPV6_PRIORITY_UNCHARACTERIZED 0x0000 #define IPV6_PRIORITY_FILLER 0x0100 #define IPV6_PRIORITY_UNATTENDED 0x0200 #define IPV6_PRIORITY_RESERVED1 0x0300 #define IPV6_PRIORITY_BULK 0x0400 #define IPV6_PRIORITY_RESERVED2 0x0500 #define IPV6_PRIORITY_INTERACTIVE 0x0600 #define IPV6_PRIORITY_CONTROL 0x0700 #define IPV6_PRIORITY_8 0x0800 #define IPV6_PRIORITY_9 0x0900 #define IPV6_PRIORITY_10 0x0a00 #define IPV6_PRIORITY_11 0x0b00 #define IPV6_PRIORITY_12 0x0c00 #define IPV6_PRIORITY_13 0x0d00 #define IPV6_PRIORITY_14 0x0e00 #define IPV6_PRIORITY_15 0x0f00 /* * IPV6 extension headers */ #define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */ #define IPPROTO_ROUTING 43 /* IPv6 routing header */ #define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */ #define IPPROTO_ICMPV6 58 /* ICMPv6 */ #define IPPROTO_NONE 59 /* IPv6 no next header */ #define IPPROTO_DSTOPTS 60 /* IPv6 destination options */ #define IPPROTO_MH 135 /* IPv6 mobility header */ /* * IPv6 TLV options. */ #define IPV6_TLV_PAD0 0 #define IPV6_TLV_PADN 1 #define IPV6_TLV_ROUTERALERT 5 #define IPV6_TLV_JUMBO 194 #define IPV6_TLV_HAO 201 /* home address option */ /* * IPV6 socket options */ #define IPV6_ADDRFORM 1 #define IPV6_2292PKTINFO 2 #define IPV6_2292HOPOPTS 3 #define IPV6_2292DSTOPTS 4 #define IPV6_2292RTHDR 5 #define IPV6_2292PKTOPTIONS 6 #define IPV6_CHECKSUM 7 #define IPV6_2292HOPLIMIT 8 #define IPV6_NEXTHOP 9 #define IPV6_AUTHHDR 10 /* obsolete */ #define IPV6_FLOWINFO 11 #define IPV6_UNICAST_HOPS 16 #define IPV6_MULTICAST_IF 17 #define IPV6_MULTICAST_HOPS 18 #define IPV6_MULTICAST_LOOP 19 #define IPV6_ADD_MEMBERSHIP 20 #define IPV6_DROP_MEMBERSHIP 21 #define IPV6_ROUTER_ALERT 22 #define IPV6_MTU_DISCOVER 23 #define IPV6_MTU 24 #define IPV6_RECVERR 25 #define IPV6_V6ONLY 26 #define IPV6_JOIN_ANYCAST 27 #define IPV6_LEAVE_ANYCAST 28 /* IPV6_MTU_DISCOVER values */ #define IPV6_PMTUDISC_DONT 0 #define IPV6_PMTUDISC_WANT 1 #define IPV6_PMTUDISC_DO 2 #define IPV6_PMTUDISC_PROBE 3 /* Flowlabel */ #define IPV6_FLOWLABEL_MGR 32 #define IPV6_FLOWINFO_SEND 33 #define IPV6_IPSEC_POLICY 34 #define IPV6_XFRM_POLICY 35 /* * Multicast: * Following socket options are shared between IPv4 and IPv6. * * MCAST_JOIN_GROUP 42 * MCAST_BLOCK_SOURCE 43 * MCAST_UNBLOCK_SOURCE 44 * MCAST_LEAVE_GROUP 45 * MCAST_JOIN_SOURCE_GROUP 46 * MCAST_LEAVE_SOURCE_GROUP 47 * MCAST_MSFILTER 48 */ /* * Advanced API (RFC3542) (1) * * Note: IPV6_RECVRTHDRDSTOPTS does not exist. see net/ipv6/datagram.c. */ #define IPV6_RECVPKTINFO 49 #define IPV6_PKTINFO 50 #define IPV6_RECVHOPLIMIT 51 #define IPV6_HOPLIMIT 52 #define IPV6_RECVHOPOPTS 53 #define IPV6_HOPOPTS 54 #define IPV6_RTHDRDSTOPTS 55 #define IPV6_RECVRTHDR 56 #define IPV6_RTHDR 57 #define IPV6_RECVDSTOPTS 58 #define IPV6_DSTOPTS 59 #if 0 /* not yet */ #define IPV6_RECVPATHMTU 60 #define IPV6_PATHMTU 61 #define IPV6_DONTFRAG 62 #define IPV6_USE_MIN_MTU 63 #endif /* * Netfilter (1) * * Following socket options are used in ip6_tables; * see include/linux/netfilter_ipv6/ip6_tables.h. * * IP6T_SO_SET_REPLACE / IP6T_SO_GET_INFO 64 * IP6T_SO_SET_ADD_COUNTERS / IP6T_SO_GET_ENTRIES 65 */ /* * Advanced API (RFC3542) (2) */ #define IPV6_RECVTCLASS 66 #define IPV6_TCLASS 67 /* * Netfilter (2) * * Following socket options are used in ip6_tables; * see include/linux/netfilter_ipv6/ip6_tables.h. * * IP6T_SO_GET_REVISION_MATCH 68 * IP6T_SO_GET_REVISION_TARGET 69 */ /* RFC5014: Source address selection */ #define IPV6_ADDR_PREFERENCES 72 #define IPV6_PREFER_SRC_TMP 0x0001 #define IPV6_PREFER_SRC_PUBLIC 0x0002 #define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100 #define IPV6_PREFER_SRC_COA 0x0004 #define IPV6_PREFER_SRC_HOME 0x0400 #define IPV6_PREFER_SRC_CGA 0x0008 #define IPV6_PREFER_SRC_NONCGA 0x0800 /* * Multicast Routing: * see include/linux/mroute6.h. * * MRT6_INIT 200 * MRT6_DONE 201 * MRT6_ADD_MIF 202 * MRT6_DEL_MIF 203 * MRT6_ADD_MFC 204 * MRT6_DEL_MFC 205 * MRT6_VERSION 206 * MRT6_ASSERT 207 * MRT6_PIM 208 * (reserved) 209 */ /* The following constants should be used for the second parameter of `shutdown'. */ enum { SHUT_RD = 0, /* No more receptions. */ #define SHUT_RD SHUT_RD SHUT_WR, /* No more transmissions. */ #define SHUT_WR SHUT_WR SHUT_RDWR /* No more receptions or transmissions. */ #define SHUT_RDWR SHUT_RDWR }; /* Add more `struct sockaddr_AF' types here as necessary. These are all the ones I found on NetBSD and Linux. */ # define __SOCKADDR_ALLTYPES \ __SOCKADDR_ONETYPE (sockaddr) \ __SOCKADDR_ONETYPE (sockaddr_at) \ __SOCKADDR_ONETYPE (sockaddr_ax25) \ __SOCKADDR_ONETYPE (sockaddr_dl) \ __SOCKADDR_ONETYPE (sockaddr_eon) \ __SOCKADDR_ONETYPE (sockaddr_in) \ __SOCKADDR_ONETYPE (sockaddr_in6) \ __SOCKADDR_ONETYPE (sockaddr_inarp) \ __SOCKADDR_ONETYPE (sockaddr_ipx) \ __SOCKADDR_ONETYPE (sockaddr_iso) \ __SOCKADDR_ONETYPE (sockaddr_ns) \ __SOCKADDR_ONETYPE (sockaddr_un) \ __SOCKADDR_ONETYPE (sockaddr_x25) # define __SOCKADDR_ONETYPE(type) struct type *__restrict __##type##__; typedef union { __SOCKADDR_ALLTYPES } __SOCKADDR_ARG __attribute__ ((__transparent_union__)); # undef __SOCKADDR_ONETYPE # define __SOCKADDR_ONETYPE(type) __const struct type *__restrict __##type##__; typedef union { __SOCKADDR_ALLTYPES } __CONST_SOCKADDR_ARG __attribute__ ((__transparent_union__)); # undef __SOCKADDR_ONETYPE /* Create a new socket of type TYPE in domain DOMAIN, using protocol PROTOCOL. If PROTOCOL is zero, one is chosen automatically. Returns a file descriptor for the new socket, or -1 for errors. */ extern int socket (int __domain, int __type, int __protocol) __THROW; /* Create two new sockets, of type TYPE in domain DOMAIN and using protocol PROTOCOL, which are connected to each other, and put file descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, one will be chosen automatically. Returns 0 on success, -1 for errors. */ extern int socketpair (int __domain, int __type, int __protocol, int __fds[2]) __THROW; /* Give the socket FD the local address ADDR (which is LEN bytes long). */ extern int bind (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len) __THROW; /* Put the local address of FD into *ADDR and its length in *LEN. */ extern int getsockname (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __len) __THROW; /* Open a connection on socket FD to peer at ADDR (which LEN bytes long). For connectionless socket types, just set the default address to send to and the only address from which to accept transmissions. Return 0 on success, -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern int connect (int __fd, __CONST_SOCKADDR_ARG __addr, socklen_t __len); /* Put the address of the peer connected to socket FD into *ADDR (which is *LEN bytes long), and its actual length into *LEN. */ extern int getpeername (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __len) __THROW; /* Return entry from network data base for network with NAME and protocol PROTO. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct servent *getservbyname (__const char *__name, __const char *__proto); /* Check the first NFDS descriptors each in READFDS (if not NULL) for read readiness, in WRITEFDS (if not NULL) for write readiness, and in EXCEPTFDS (if not NULL) for exceptional conditions. If TIMEOUT is not NULL, time out after waiting the interval specified therein. Returns the number of ready descriptors, or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern int select (int __nfds, fd_set *__restrict __readfds, fd_set *__restrict __writefds, fd_set *__restrict __exceptfds, struct timeval *__restrict __timeout); /* Send N bytes of BUF to socket FD. Returns the number sent or -1. This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t send (int __fd, __const void *__buf, size_t __n, int __flags); /* Read N bytes into BUF from socket FD. Returns the number read or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t recv (int __fd, void *__buf, size_t __n, int __flags); /* Send N bytes of BUF on socket FD to peer at address ADDR (which is ADDR_LEN bytes long). Returns the number sent, or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t sendto (int __fd, __const void *__buf, size_t __n, int __flags, __CONST_SOCKADDR_ARG __addr, socklen_t __addr_len); /* Read N bytes into BUF through socket FD. If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address of the sender, and store the actual size of the address in *ADDR_LEN. Returns the number of bytes read or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t recvfrom (int __fd, void *__restrict __buf, size_t __n, int __flags, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len); /* Send a message described MESSAGE on socket FD. Returns the number of bytes sent, or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t sendmsg (int __fd, __const struct msghdr *__message, int __flags); /* Receive a message as described by MESSAGE from socket FD. Returns the number of bytes read or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern ssize_t recvmsg (int __fd, struct msghdr *__message, int __flags); /* Put the current value for socket FD's option OPTNAME at protocol level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set *OPTLEN to the value's actual length. Returns 0 on success, -1 for errors. */ extern int getsockopt (int __fd, int __level, int __optname, void *__restrict __optval, socklen_t *__restrict __optlen) __THROW; /* Set socket FD's option OPTNAME at protocol level LEVEL to *OPTVAL (which is OPTLEN bytes long). Returns 0 on success, -1 for errors. */ extern int setsockopt (int __fd, int __level, int __optname, __const void *__optval, socklen_t __optlen) __THROW; /* Prepare to accept connections on socket FD. N connection requests will be queued before further requests are refused. Returns 0 on success, -1 for errors. */ extern int listen (int __fd, int __n) __THROW; /* Await a connection on socket FD. When a connection arrives, open a new socket to communicate with it, set *ADDR (which is *ADDR_LEN bytes long) to the address of the connecting peer and *ADDR_LEN to the address's actual length, and return the new socket's descriptor, or -1 for errors. This function is a cancellation point and therefore not marked with __THROW. */ extern int accept (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len); #define __nonnull(x) #define __USE_BSD 1 #define __wur #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED || defined __USE_XOPEN2K /* Truncate the file FD is open on to LENGTH bytes. */ # ifndef __USE_FILE_OFFSET64 extern int ftruncate (int __fd, __off_t __length) __THROW __wur; # else # ifdef __REDIRECT_NTH extern int __REDIRECT_NTH (ftruncate, (int __fd, __off64_t __length), ftruncate64) __wur; # else # define ftruncate ftruncate64 # endif # endif # ifdef __USE_LARGEFILE64 extern int ftruncate64 (int __fd, __off64_t __length) __THROW __wur; # endif #endif /* Use BSD || X/Open Unix || POSIX 2003. */ #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED # ifndef __USE_FILE_OFFSET64 /* Get file attributes about FILE and put them in BUF. If FILE is a symbolic link, do not follow it. */ extern int lstat (__const char *__restrict __file, struct stat *__restrict __buf) __THROW __nonnull ((1, 2)); # else # ifdef __REDIRECT_NTH extern int __REDIRECT_NTH (lstat, (__const char *__restrict __file, struct stat *__restrict __buf), lstat64) __nonnull ((1, 2)); # else # define lstat lstat64 # endif # endif # ifdef __USE_LARGEFILE64 extern int lstat64 (__const char *__restrict __file, struct stat64 *__restrict __buf) __THROW __nonnull ((1, 2)); # endif #endif /* Create a device file named PATH, with permission and special bits MODE and device number DEV (which can be constructed from major and minor device numbers with the `makedev' macro above). */ #if defined __USE_MISC || defined __USE_BSD || defined __USE_XOPEN_EXTENDED extern int mknod (__const char *__path, __mode_t __mode, __dev_t __dev) __THROW __nonnull ((1)); #endif /* Create a new FIFO named PATH, with permission bits MODE. */ extern int mkfifo (__const char *__path, __mode_t __mode) __THROW __nonnull ((1)); /* Set the file creation mask of the current process to MASK, and return the old creation mask. */ extern __mode_t umask (__mode_t __mask) __THROW; /* Set the access and modification times of FILE to those given in *FILE_TIMES. If FILE_TIMES is NULL, set them to the current time. */ extern int utime (__const char *__file, __const struct utimbuf *__file_times) __THROW __nonnull ((1)); /* Rewind DIRP to the beginning of the directory. */ extern void rewinddir (DIR *__dirp) __THROW __nonnull ((1)); #if defined __USE_BSD || defined __USE_XOPEN_EXTENDED /* Put the absolute pathname of the current working directory in BUF. If successful, return BUF. If not, put an error message in BUF and return NULL. BUF should be at least PATH_MAX bytes long. */ extern char *getwd (char *__buf) __THROW __nonnull ((1)) __wur; #endif #if defined __USE_BSD || defined __USE_UNIX98 /* Put the name of the current host in no more than LEN bytes of NAME. The result is null-terminated if LEN is large enough for the full name and the terminator. */ extern int gethostname (char *__name, size_t __len) __THROW __nonnull ((1)); #endif /* Return entry from host data base which address match ADDR with length LEN and type TYPE. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct hostent *gethostbyaddr (__const void *__addr, __socklen_t __len, int __type); /* Return entry from host data base for host with NAME. This function is a possible cancellation point and therefore not marked with __THROW. */ extern struct hostent *gethostbyname (__const char *__name); #ifdef __USE_GNU /* Similar to 'accept' but takes an additional parameter to specify flags. This function is a cancellation point and therefore not marked with __THROW. */ extern int accept4 (int __fd, __SOCKADDR_ARG __addr, socklen_t *__restrict __addr_len, int __flags); #endif /* Shut down all or part of the connection open on socket FD. HOW determines what to shut down: SHUT_RD = No more receptions; SHUT_WR = No more transmissions; SHUT_RDWR = No more receptions or transmissions. Returns 0 on success, -1 for errors. */ extern int shutdown (int __fd, int __how) __THROW; #ifdef __USE_XOPEN2K /* Determine wheter socket is at a out-of-band mark. */ extern int sockatmark (int __fd) __THROW; #endif #ifdef __USE_MISC /* FDTYPE is S_IFSOCK or another S_IF* macro defined in <sys/stat.h>; returns 1 if FD is open on an object of the indicated type, 0 if not, or -1 for errors (setting errno). */ extern int isfdtype (int __fd, int __fdtype) __THROW; #endif /* Define some macros helping to catch buffer overflows. */ #if __USE_FORTIFY_LEVEL > 0 && defined __extern_always_inline # include <bits/socket2.h> #endif #define __USE_POSIX #define __USE_GNU /* Extension from POSIX.1g. */ #ifdef __USE_POSIX # ifdef __USE_GNU /* Lookup mode. */ # define GAI_WAIT 0 # define GAI_NOWAIT 1 # endif /* Possible values for `ai_flags' field in `addrinfo' structure. */ # define AI_PASSIVE 0x0001 /* Socket address is intended for `bind'. */ # define AI_CANONNAME 0x0002 /* Request for canonical name. */ # define AI_NUMERICHOST 0x0004 /* Don't use name resolution. */ # define AI_V4MAPPED 0x0008 /* IPv4 mapped addresses are acceptable. */ # define AI_ALL 0x0010 /* Return IPv4 mapped and IPv6 addresses. */ # define AI_ADDRCONFIG 0x0020 /* Use configuration of this host to choose returned address type.. */ # ifdef __USE_GNU # define AI_IDN 0x0040 /* IDN encode input (assuming it is encoded in the current locale's character set) before looking it up. */ # define AI_CANONIDN 0x0080 /* Translate canonical name from IDN format. */ # define AI_IDN_ALLOW_UNASSIGNED 0x0100 /* Don't reject unassigned Unicode code points. */ # define AI_IDN_USE_STD3_ASCII_RULES 0x0200 /* Validate strings according to STD3 rules. */ # endif # define AI_NUMERICSERV 0x0400 /* Don't use name resolution. */ /* Error values for `getaddrinfo' function. */ # define EAI_BADFLAGS -1 /* Invalid value for `ai_flags' field. */ # define EAI_NONAME -2 /* NAME or SERVICE is unknown. */ # define EAI_AGAIN -3 /* Temporary failure in name resolution. */ # define EAI_FAIL -4 /* Non-recoverable failure in name res. */ # define EAI_FAMILY -6 /* `ai_family' not supported. */ # define EAI_SOCKTYPE -7 /* `ai_socktype' not supported. */ # define EAI_SERVICE -8 /* SERVICE not supported for `ai_socktype'. */ # define EAI_MEMORY -10 /* Memory allocation failure. */ # define EAI_SYSTEM -11 /* System error returned in `errno'. */ # define EAI_OVERFLOW -12 /* Argument buffer overflow. */ # ifdef __USE_GNU # define EAI_NODATA -5 /* No address associated with NAME. */ # define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */ # define EAI_INPROGRESS -100 /* Processing request in progress. */ # define EAI_CANCELED -101 /* Request canceled. */ # define EAI_NOTCANCELED -102 /* Request not canceled. */ # define EAI_ALLDONE -103 /* All requests done. */ # define EAI_INTR -104 /* Interrupted by a signal. */ # define EAI_IDN_ENCODE -105 /* IDN encoding failed. */ # endif #define __USE_MISC # ifdef __USE_MISC # define NI_MAXHOST 1025 # define NI_MAXSERV 32 # endif # define NI_NUMERICHOST 1 /* Don't try to look up hostname. */ # define NI_NUMERICSERV 2 /* Don't convert port number to name. */ # define NI_NOFQDN 4 /* Only return nodename portion. */ # define NI_NAMEREQD 8 /* Don't return numeric addresses. */ # define NI_DGRAM 16 /* Look up UDP service rather than TCP. */ # ifdef __USE_GNU # define NI_IDN 32 /* Convert name from IDN format. */ # define NI_IDN_ALLOW_UNASSIGNED 64 /* Don't reject unassigned Unicode code points. */ # define NI_IDN_USE_STD3_ASCII_RULES 128 /* Validate strings according to STD3 rules. */ /* Translate name of a service location and/or a service name to set of socket addresses. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getaddrinfo (__const char *__restrict __name, __const char *__restrict __service, __const struct addrinfo *__restrict __req, struct addrinfo **__restrict __pai); /* Free `addrinfo' structure AI including associated storage. */ extern void freeaddrinfo (struct addrinfo *__ai) __THROW; /* Convert error return from getaddrinfo() to a string. */ extern __const char *gai_strerror (int __ecode) __THROW; /* Translate a socket address to a location and service name. This function is a possible cancellation point and therefore not marked with __THROW. */ extern int getnameinfo (__const struct sockaddr *__restrict __sa, socklen_t __salen, char *__restrict __host, socklen_t __hostlen, char *__restrict __serv, socklen_t __servlen, unsigned int __flags); # endif /* POSIX */ #endif /* We can optimize calls to the conversion functions. Either nothing has to be done or we are using directly the byte-swapping functions which often can be inlined. */ # if __BYTE_ORDER == __BIG_ENDIAN /* The host byte order is the same as network byte order, so these functions are all just identity. */ # define ntohl(x) (x) # define ntohs(x) (x) # define htonl(x) (x) # define htons(x) (x) # else # if __BYTE_ORDER == __LITTLE_ENDIAN # define ntohl(x) __bswap_32 (x) # define ntohs(x) __bswap_16 (x) # define htonl(x) __bswap_32 (x) # define htons(x) __bswap_16 (x) # endif # endif extern int timezone; /* Convert Internet number in IN to ASCII representation. The return value is a pointer to an internal array containing the string. */ extern char *inet_ntoa (struct in_addr __in) __THROW; |
Added nacl/tcl.nmf.
> > > > > > | 1 2 3 4 5 6 | { "program": { "x86-32": {"url":"tcl32.nexe"}, "x86-64": {"url":"tcl64.nexe"} } } |
Added nacl/tclUnixPort.h.patch.
> > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | --- tclUnixPort.h 2011-04-04 20:36:08.686478500 +0200 +++ tclUnixPort.h 2011-04-06 23:10:38.296769763 +0200 @@ -138,6 +138,7 @@ *--------------------------------------------------------------------------- */ +#ifndef NACL #include <sys/socket.h> /* struct sockaddr, SOCK_STREAM, ... */ #ifndef NO_UNAME # include <sys/utsname.h> /* uname system call. */ @@ -148,6 +149,11 @@ #ifdef NEED_FAKE_RFC2553 # include "../compat/fake-rfc2553.h" #endif +#else /* NACL */ + +#include "naclcompat.h" + +#endif /* NACL */ /* *--------------------------------------------------------------------------- |
Added nacl/tools/natcl2tk.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #! /bin/sh #\ exec wish $0 "$@" if {!$argc} { puts stderr "Usage: [file tail $::argv0] <file.natcl> \[<file.natcl> ...\]" exit 1 } foreach fn $argv { set direct($fn) 1 } set mydir [info script].dir rename source _source proc source fn { if {![info exists ::direct($fn)]} { set fn $::mydir/[file tail $fn] } uplevel 1 [list _source $fn] } proc domset {x y} {wm title . $y} set ::uniqEv 1 proc every {ms scr} { set fn every#$::uniqEv incr ::uniqEv proc $fn {} "after $ms $fn;uplevel #0 {$scr}" after 0 $fn } proc printf s {puts stderr $s} source [lindex $argv 0] |
Added nacl/tools/natcl2tk.dir/canv.natcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | # # emu/canv.tcl: reimplement NaTcl's canv verbs in Tk # set width 578 set height 200 canvas .c -width $width -height $height -bg white pack .c update proc canv_create {ty a b c args} { switch -exact -- $ty { circle { set cc [list [expr {$a-$c}] [expr {$b-$c}] \ [expr {$a+$c}] [expr {$b+$c}]] set ty oval } default { error "Unknown canv item type '$ty'" } } set it [eval .c create $ty $cc $args] set ::canvx($it) $a set ::canvy($it) $b return $it } proc canv_moveto {it x y} { set dx [expr {$x-$::canvx($it)}] set ::canvx($it) $x set dy [expr {$y-$::canvy($it)}] set ::canvy($it) $y .c move $it $dx $dy } proc canv_bind {evt cb} { switch -exact -- $evt { <Motion> { bind .c <Motion> "$cb %x %y" } <Enter> - <Leave> { bind .c $evt $cb } default { error "Unknown canv event type '$evt'" } } } |
Added nacl/tools/tocstr.
> > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 | #! /bin/sh #\ exec tclsh $0 "$@" while {[gets stdin line]>=0} { regsub -all {[""\\]} $line {\\&} line puts " \"$line\\n\"" } flush stdout exit 0 |
Added nacl/trivhttpd.tcl.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | #! /bin/sh #\ exec tclsh $0 "$@" if {$argc!=1} {puts stderr "Usage: [file tail $::argv0] <port>";exit 1} set port [lindex $argv 0] proc serve {sok h p} { fconfigure $sok -translation binary -buffering full if {[catch { if {[gets $sok line]<0} {error "400 Empty request"} if {![regexp {^GET[ ]+([^ ]+)} $line -> path]} {error "403 Method Not Supported"} puts stderr "$h:$p - GET $path" if {[regexp {[.][.]} $path]} {error "403 Forbidden"} set ty text/plain switch -glob [file extension $path] { .html {set ty text/html} .nexe - .nmf {set ty application/octet-stream} } if {[catch {set ff [open .$path r]}]} {error "404 File Not Found"} fconfigure $ff -translation binary set data [read $ff] close $ff } err]} { puts $sok "HTTP/1.0 $err\r\n\r" } else { puts -nonewline $sok "HTTP/1.0 200 OK\r\nContent-Type: $ty\r\nContent-Length: [string length $data]\r\n\r\n$data" } close $sok } socket -server serve $port vwait forever |