diff --git a/pd/nw/pdgui.js b/pd/nw/pdgui.js index e110bdf3272450436f6570c2780a8e4ce4421051..b8e82d77477361a089e884fb7e5fd532eb5749d8 100644 --- a/pd/nw/pdgui.js +++ b/pd/nw/pdgui.js @@ -1734,55 +1734,71 @@ exports.connect = connect; // on ";", and the side effect can be removed. // can be removed. -// StringDecoder is used to make sure UTF8 characters which happen to -// straddle buffers get handled correctly. If this proves too slow, there's -// a Buffer Tools lib in Node.js that's more powerful. But for now this seems -// fine... -var StringDecoder = require('string_decoder').StringDecoder; - function init_socket_events () { - var decoder = new StringDecoder('utf8'); - var nextCmd = ""; // Build up a command across lines (or buffers) - var cmdHeader = 0; + var next_command = ''; // A not-quite-FUDI command: selector arg1,arg2,etc. + // These are formatted on the C side to be easy + // to parse here in javascript + var old_command = ''; // Old-style sys_vgui cmds (and print to console) + var cmdHeader = false; client.on('data', function(data) { - var dataStr = decoder.write(data); + var i, len, selector, args; //var dataStr = data.toString(); // For debugging the buffer... //if (decoder.end() !== "") { // console.log("utf8 multi-byte character split across buffer"); // console.log("end bytes are " + decoder.end()); //} - var arr = dataStr.split("\n"); - var arrLen = arr.length; - for (var i = 0; i < arrLen; i++) { - var prefix = arr[i].substring(0, 2); - if (prefix == 'nw' || prefix == 'nn') { - nextCmd = arr[i].substring(3); - //console.log("nextCmd is " + nextCmd); - cmdHeader = 1; - } else if (cmdHeader) { - nextCmd += arr[i]; - //console.log("2nd part of cmd is " + arr[i]); + + len = data.length; + for (i = 0; i < len; i++) { + if (cmdHeader) { + // check for end of command: \v + if (data[i] === 11) { // vertical tab '\v' + // decode next_command + try { + // This should work for all utf-8 content + next_command = decodeURIComponent(next_command); + } + catch(err) { + // This should work for ISO-8859-1 + next_command = unescape(next_command); + } + // Turn newlines into backslash + 'n' so + // eval will do the right thing + next_command = next_command.replace(/\n/g, '\\n'); + selector = next_command.slice(0, next_command.indexOf(" ")); + args = next_command.slice(selector.length + 1); + cmdHeader = false; + next_command = ''; + // Now evaluate it + //gui_post('Evaling: ' + selector + '(' + args + ');'); + eval(selector + '(' + args + ');'); + } else { + next_command += '%' + + ('0' // leading zero (for rare case of single digit) + + data[i].toString(16)) // to hex + .slice(-2); // remove extra leading zero + } + } else if (data[i] === 7) { // ASCII alarm bell '\a' + // if we have an old-style message, print it out + if (old_command !== '') { + var old_command_output; + try { + old_command_output = decodeURIComponent(old_command); + } + catch(err) { + old_command_output = unescape(old_command); + } + old_command= ''; + gui_post("warning: old command: " + old_command_output); + } + cmdHeader = true; } else { - // Show the remaining old tcl/tk messages in blue - gui_post(arr[i], "blue"); - } - // check if we end with a semicolon followed by a newline - if (nextCmd.slice(-1) === ";" && nextCmd.slice(-2) !== '\\') { - //nextCmd = nextCmd.replace(/\n/g, "\\n"); - //nextCmd = nextCmd.replace(/'/g, "\\\'"); - var selector = nextCmd.slice(0, nextCmd.indexOf(" ")); - var args = nextCmd.slice(selector.length + 1, -1); - //console.log('About to eval: ' + selector + '(' + args + ');'); - eval(selector + '(' + args + ');'); - nextCmd = ''; - cmdHeader = 0; + // this is an old-style sys_vgui + old_command += '%' + ('0' + data[i].toString(16)).slice(-2); } - } - // client.destroy(); - // console.log('Connection closed'); - + } }); // Add a 'close' event handler for the client socket @@ -2131,7 +2147,7 @@ function text_to_tspans(canvasname, svg_text, text) { } function gui_text_new(canvasname, myname, type, isselected, x, y, text, font) { -// gui_post("font is " + font); + gui_post("font is " + font); var lines, i, len, tspan; var g = get_gobj(canvasname, myname); var svg_text = create_item(canvasname, 'text', { @@ -3558,10 +3574,10 @@ function gui_canvas_getscroll(cid) { }); svg.width.baseVal.valueAsString = width; svg.height.baseVal.valueAsString = height; - console.log("x is " + bbox.x); - console.log("y is " + bbox.x); - console.log("width is " + bbox.width); - console.log("height is " + bbox.height); +// console.log("x is " + bbox.x); +// console.log("y is " + bbox.x); +// console.log("width is " + bbox.width); +// console.log("height is " + bbox.height); } // handling the selection diff --git a/pd/nw/todo.txt b/pd/nw/todo.txt index 7fca93e1bafeeb81788e1b9bfdd5b14db236986a..8755b9f0499d76eb17cc32ab782088f9361e420c 100644 --- a/pd/nw/todo.txt +++ b/pd/nw/todo.txt @@ -197,6 +197,8 @@ Everything else: (A [x] means we've fixed it) [ ] clip garray to gl_x1 and gl_x2 by: a) checking if we're in a gop, and b) if so, only render if element number is > gl_x1 and < gl_x2 +[ ] fix bug where utf_8 snowmen in an object box can cause a buffer overflow + in the lib loading routine Crashers -------- diff --git a/pd/src/s_inter.c b/pd/src/s_inter.c index 52311ee4f02cd731faf4d9fd46eb335fdd2c392c..147c815a9c616f847dd87c5955f3df74a8afb58e 100644 --- a/pd/src/s_inter.c +++ b/pd/src/s_inter.c @@ -771,6 +771,12 @@ char *escape_double_quotes(const char *src) { return ret; } +void gui_end_vmess(void) +{ + sys_gui("\v"); +} + + /* quick hack to send a parameter list for use as a function call in Node-Webkit */ void gui_do_vmess(const char *sel, char *fmt, int end, va_list ap) @@ -780,7 +786,9 @@ void gui_do_vmess(const char *sel, char *fmt, int end, va_list ap) char *fp = fmt; //va_start(ap, end); - sys_vgui("nn %s ", sel); + sys_vgui("\a%s ", sel); /* use a bell to signal the beginning of msg + (this can be replaced with any other obscure + ascii escape) */ while (*fp) { // stop-gap-- increase to 20 until we find a way to pass a list or array @@ -804,7 +812,7 @@ void gui_do_vmess(const char *sel, char *fmt, int end, va_list ap) done: va_end(ap); if (end) - sys_gui(";\n"); + gui_end_vmess(); } void gui_vmess(const char *sel, char *fmt, ...) @@ -875,11 +883,6 @@ void gui_end_array(void) gui_array_tail = 1; } -void gui_end_vmess(void) -{ - sys_gui(";\n"); -} - int sys_flushtogui( void) { int writesize = sys_guibufhead - sys_guibuftail, nwrote = 0;