diff --git a/exec/dorkit/ansi_input.js b/exec/dorkit/ansi_input.js index 7d8d8c5cd3ce5e4ac079e2bdee203f3249406c32..b49d7640da50e302604da033a5a7943ed27f9c14 100644 --- a/exec/dorkit/ansi_input.js +++ b/exec/dorkit/ansi_input.js @@ -1,6 +1,7 @@ var ai={ charbuf:'', ansi_started:0, + input_queue:new Queue("dorkit_input"), // Called every 100ms *and* every char. add:function(ch) { @@ -8,13 +9,12 @@ var ai={ var q; var byte; var m; - q = new Queue("dorkit_input"); if (ch == '\x1b') { if (this.ansi_started) { for(i=0; i<this.charbuf.length; i++) { byte = this.charbuf.substr(i,1) - q.write(byte); + this.input_queue.write(byte); } } this.ansi_started = Date.now(); @@ -25,7 +25,7 @@ var ai={ // Add the character to charbuf. if (ch !== undefined && ch.length > 0) { if (!this.ansi_started) { - q.write(ch); + this.input_queue.write(ch); return; } @@ -37,25 +37,25 @@ var ai={ case '\x1b[A': case '\x1bOA': case '\x1bA': - q.write("KEY_UP\x00"+this.charbuf); + this.input_queue.write("KEY_UP\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[B': case '\x1bOB': case '\x1bB': - q.write("KEY_DOWN\x00"+this.charbuf); + this.input_queue.write("KEY_DOWN\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[C': case '\x1bOC': case '\x1bC': - q.write("KEY_RIGHT\x00"+this.charbuf); + this.input_queue.write("KEY_RIGHT\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[D': case '\x1bOD': case '\x1bD': - q.write("KEY_LEFT\x00"+this.charbuf); + this.input_queue.write("KEY_LEFT\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1bH': @@ -64,108 +64,108 @@ var ai={ case '\x1b[L': case '\x1b[w': case '\x1b[OH': - q.write("KEY_HOME\x00"+this.charbuf); + this.input_queue.write("KEY_HOME\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1bK': case '\x1b[K': case '\x1b[4~': case '\x1bOK': - q.write("KEY_END\x00"+this.charbuf); + this.input_queue.write("KEY_END\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1bP': case '\x1bOP': case '\x1b[11~': - q.write("KEY_F1\x00"+this.charbuf); + this.input_queue.write("KEY_F1\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1bQ': case '\x1bOQ': case '\x1b[12~': - q.write("KEY_F2\x00"+this.charbuf); + this.input_queue.write("KEY_F2\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?w': case '\x1bOR': case '\x1bOw': case '\x1b[13~': - q.write("KEY_F3\x00"+this.charbuf); + this.input_queue.write("KEY_F3\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?x': case '\x1bOS': case '\x1bOx': case '\x1b[14~': - q.write("KEY_F4\x00"+this.charbuf); + this.input_queue.write("KEY_F4\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?t': case '\x1bOt': case '\x1b[15~': - q.write("KEY_F5\x00"+this.charbuf); + this.input_queue.write("KEY_F5\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?u': case '\x1b[17~': case '\x1bOu': - q.write("KEY_F6\x00"+this.charbuf); + this.input_queue.write("KEY_F6\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?q': case '\x1b[18~': case '\x1bOq': - q.write("KEY_F7\x00"+this.charbuf); + this.input_queue.write("KEY_F7\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?r': case '\x1b[19~': case '\x1bOr': - q.write("KEY_F8\x00"+this.charbuf); + this.input_queue.write("KEY_F8\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b?p': case '\x1b[20~': case '\x1bOp': - q.write("KEY_F9\x00"+this.charbuf); + this.input_queue.write("KEY_F9\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[21~': - q.write("KEY_F10\x00"+this.charbuf); + this.input_queue.write("KEY_F10\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[23~': - q.write("KEY_F11\x00"+this.charbuf); + this.input_queue.write("KEY_F11\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[24~': - q.write("KEY_F12\x00"+this.charbuf); + this.input_queue.write("KEY_F12\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[M': case '\x1b[V': case '\x1b[5~': - q.write("KEY_PGUP\x00"+this.charbuf); + this.input_queue.write("KEY_PGUP\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[U': case '\x1b[6~': - q.write("KEY_PGDOWN\x00"+this.charbuf); + this.input_queue.write("KEY_PGDOWN\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[@': case '\x1b[2~': - q.write("KEY_INS\x00"+this.charbuf); + this.input_queue.write("KEY_INS\x00"+this.charbuf); this.ansi_started = 0; break; case '\x1b[3~': - q.write("KEY_DEL\x00"+this.charbuf); + this.input_queue.write("KEY_DEL\x00"+this.charbuf); this.ansi_started = 0; break; } m = this.charbuf.match(/^\x1b\[([0-9]+);([0-9]+)R$/); if (m !== null) { - q.write(format("POSITION_"+m[1]+"_"+m[2]+"\x00"+this.charbuf)); + this.input_queue.write(format("POSITION_"+m[1]+"_"+m[2]+"\x00"+this.charbuf)); this.ansi_started = 0; } if (!this.ansi_started) @@ -177,7 +177,7 @@ var ai={ if (this.charbuf.length > 10 || (this.ansi_started && this.ansi_started + 100 < Date.now())) { for(i=0; i<this.charbuf.length; i++) { byte = this.charbuf.substr(i,1) - q.write(byte); + this.input_queue.write(byte); } this.ansi_started = 0; } diff --git a/exec/dorkit/attribute.js b/exec/dorkit/attribute.js index b980047bf6d8eab7e4f2df0121df5027d06c39b6..f43699f08a105cf470f33fe21367cbde1844c4f9 100644 --- a/exec/dorkit/attribute.js +++ b/exec/dorkit/attribute.js @@ -77,6 +77,7 @@ Attribute.prototype = { this.value |= (val & 0x07); }, + _curatr:new Attribute(7), ansi:function(curatr) { var str=""; if(curatr !== undefined && curatr.value === this.value) @@ -88,7 +89,7 @@ Attribute.prototype = { || (!(this.blink) && curatr.blink) || this.value === 7) { str += "0;"; if (curatr === undefined) - curatr = new Attribute(7); + curatr = this.curatr; curatr.value = 7; } if(this.blink) { /* special attributes */ diff --git a/exec/dorkit/jsexec_input.js b/exec/dorkit/jsexec_input.js index 426a3fb9868fede53027f8793896cf3976a8e129..833d3db3d9824d6e74d2f294ea0553ecf46195a7 100644 --- a/exec/dorkit/jsexec_input.js +++ b/exec/dorkit/jsexec_input.js @@ -1,7 +1,6 @@ js.load_path_list.unshift(js.exec_dir+"/dorkit/"); js.load_path_list.unshift(system.exec_dir+"/dorkit/"); load('ansi_input.js'); -var q = new Queue("dorkit_input"); var k; while(!js.terminated) { diff --git a/exec/dorkit/screen.js b/exec/dorkit/screen.js index 5d65da7a9f911f18484653a8d2397e2609cb5cd6..5199ae1e46bbd6f8a98d9c56a2184fb052f7996e 100644 --- a/exec/dorkit/screen.js +++ b/exec/dorkit/screen.js @@ -20,6 +20,9 @@ function Screen(w, h, attr, fill) this.stored_pos = {x:0, y:0}; this.attr = new Attribute(7); } +Screen.ANSIRe = /^(.*?)\x1b\[([<-\?]{0,1})([0-;]*)([ -\/]*)([@-~])([\x00-\xff]*)$/; +Screen.ANSIFragRe = /^(.*?)(\x1b(\[([<-\?]{0,1})([0-;]*)([ -\/]*)([@-~])?)?)$/; +Screen.StripColonRe = /:[^;:]*/g; Screen.prototype.print=function(str) { var m; @@ -33,16 +36,18 @@ Screen.prototype.print=function(str) { var i; var tg; var seq; + var x; + var y; function writech(scr, ch) { var i; - var gr; function check_scrollup(scr) { + var i; + while (scr.pos.y >= scr.graphic.height) { // Scroll up... - gr = scr.graphic.get(0,1,scr.graphic.width-1, scr.graphic.height-2); - scr.graphic.put(gr,0,0); + scr.graphic.copy(0,1,scr.graphic.width-1, scr.graphic.height-2, 0, 0); for (i=0; i<scr.graphic.width; i++) { scr.graphic.data[i][scr.graphic.height-1].ch = scr.graphic.ch; scr.graphic.data[i][scr.graphic.height-1].attr = scr.attr.value; @@ -73,7 +78,7 @@ Screen.prototype.print=function(str) { scr.pos.y++; check_scrollup(scr); break; - case '\x0c': // For feed (clear screen and home) + case '\x0c': // Form feed (clear screen and home) scr.graphic.clear(); scr.pos.x=0; scr.pos.y=0; @@ -83,7 +88,7 @@ Screen.prototype.print=function(str) { break; default: scr.graphic.data[scr.pos.x][scr.pos.y].ch = ch; - scr.graphic.data[scr.pos.x][scr.pos.y].attr = new Attribute(scr.attr); + scr.graphic.data[scr.pos.x][scr.pos.y].attr.value = scr.attr.value; scr.pos.x++; if (scr.pos.x >= scr.graphic.width) { scr.pos.x = 0; @@ -113,7 +118,7 @@ Screen.prototype.print=function(str) { str = this.escbuf + str; this.escbuf = ''; - while((m=str.match(/^(.*?)\x1b\[([<-\?]{0,1})([0-;]*)([ -\/]*)([@-~])([\x00-\xff]*)$/)) !== null) { + while((m=str.match(Screen.ANSIRe)) !== null) { chars = m[1]; ext = m[2]; pb = m[3]; @@ -121,8 +126,6 @@ Screen.prototype.print=function(str) { fb = m[5]; remain = m[6]; seq = ext + ib + fb; - var x; - var y; str = remain; @@ -131,7 +134,7 @@ Screen.prototype.print=function(str) { writech(this, chars[i]); // We don't support any : paramters... strip and ignore. - p = pb.replace(/:[^;:]*/g, ''); + p = pb.replace(Screen.StripColonRe, ''); p = p.split(';'); switch(fb) { @@ -139,10 +142,8 @@ Screen.prototype.print=function(str) { param_defaults(p, [1]); if (p[1] > this.graphic.width - this.pos.x) p[1] = this.graphic.width - this.pos.x; - if (this.pos.x < this.graphic.width-1) { - tg = this.graphic.get(this.pos.x, this.pos.y, this.graphic.width-1 - p[1], this.pos.y); - tg = this.graphic.put(this.pos.x + p[1], this.pos.y, this.graphic.width - 1, this.pos.y); - } + if (this.pos.x < this.graphic.width-1) + this.graphic.copy(this.pos.x, this.pos.y, this.graphic.width-1 - p[1], this.pos.y, this.pos.x + p[1], this.pos.y); for (x = 0; x<p[1]; x++) { this.graphic.data[this.pos.x + x][this.pos.y].ch = this.graphic.ch; this.graphic.data[this.pos.x + x][this.pos.y].attr = this.attr.value; @@ -241,10 +242,8 @@ Screen.prototype.print=function(str) { param_defaults(p, [1]); if (p[1] > this.graphic.width - this.pos.x) p[1] = this.graphic.width - this.pos.x; - if (this.pos.x < this.graphic.width-1) { - tg = this.graphic.get(this.pos.x + p[1], this.pos.y, this.graphic.width - 1, this.pos.y); - tg = this.graphic.put(this.pos.x, this.pos.y, (this.graphic.width - 1) - p[1], this.pos.y); - } + if (this.pos.x < this.graphic.width-1) + this.graphic.copy(this.pos.x + p[1], this.pos.y, this.graphic.width - 1, this.pos.y, this.pos.x, this.pos.y); for (x = 0; x<p[1]; x++) { this.graphic.data[(this.width - 1) - x][this.pos.y].ch = this.graphic.ch; this.graphic.data[(this.width - 1) - x][this.pos.y].attr = this.attr.value; @@ -358,7 +357,7 @@ Screen.prototype.print=function(str) { log("Sent unsupported ANSI sequence '"+ext+pb+ib+fb+"' please let shurd@sasktel.net net know about this so it can be fixed."); } } - if ((m=str.match(/^(.*?)(\x1b(\[([<-\?]{0,1})([0-;]*)([ -\/]*)([@-~])?)?)$/)) !== null) { + if ((m=str.match(Screen.ANSIFragRe)) !== null) { str = m[1]; this.escbuf = m[2]; } diff --git a/exec/load/dorkit.js b/exec/load/dorkit.js index 10ecdd4d937bc5c6e2a011f4009d147ca361bcd9..3c4f0fdfb7ef7b3f05a9f0cfc927ad87dbd12527 100644 --- a/exec/load/dorkit.js +++ b/exec/load/dorkit.js @@ -73,13 +73,17 @@ var dk = { x:1, // Current column (1-based) y:1, // Current row (1-based) _attr:new Attribute(7), + _new_attr:new Attribute(7), get attr() { return this._attr; }, set attr(val) { - var n = new Attribute(val); - this.print(n.ansi(this._attr)); - this._attr = n; + if (typeof(val)=='object') + this._new_attr.value = val.value; + else + this._new_attr.value = val; + this.print(this._new_attr.ansi(this._attr)); + this._attr.value = this._new_attr.value; }, ansi:true, // ANSI support is enabled charset:'cp437', // Supported character set @@ -91,28 +95,37 @@ var dk = { keybuf:'', local_screen:new Screen(80, 24, 7, ' '), remote_screen:new Screen(80, 24, 7, ' '), + input_queue:new Queue("dorkit_input"), /* * Returns a string with ^A codes converted to ANSI or stripped * as appropriate. */ + _orig_attr:new Attribute(7), + _next_attr:new Attribute(7), parse_ctrla:function(txt, orig_attr) { var ret=''; var i; var curr_attr; - var next_attr; + var next_attr = this._next_attr; - if (orig_attr !== undefined) - curr_attr = new Attribute(orig_attr); - next_attr = new Attribute(curr_attr); + if (orig_attr !== undefined) { + curr_attr = this._orig_attr; + curr_attr.value = orig_attr.value; + next_attr.value = curr_attr.value; + } + else + next_attr.value = 7; function attr_str() { var ansi_str; if (curr_attr === undefined || curr_attr.value != next_attr.value) { ansi_str = next_attr.ansi(curr_attr); - if (curr_attr === undefined) - curr_attr = new Attribute(next_attr); + if (curr_attr === undefined) { + curr_attr = this._orig_attr; + curr_attr.value = next_attr.value; + } else curr_attr.value = next_attr.value; return ansi_str; @@ -295,8 +308,7 @@ var dk = { * true when the entire ANSI sequence is available. */ waitkey:function(timeout) { - var q = new Queue("dorkit_input"); - if (q.poll(timeout) === false) + if (this.input_queue.poll(timeout) === false) return false; return true; }, @@ -316,8 +328,7 @@ var dk = { } if (!this.waitkey(0)) return undefined; - var q = new Queue("dorkit_input"); - ret = q.read(); + ret = this.input_queue.read(); if (ret.length > 1) { if (ret.substr(0, 9) === 'POSITION_') { m = ret.match(/^POSITION_([0-9]+)_([0-9]+)/); @@ -343,8 +354,7 @@ var dk = { } if (!this.waitkey(0)) return undefined; - var q = new Queue("dorkit_input"); - ret = q.read(); + ret = this.input_queue.read(); if (ret.length > 1) { ret=this.key[ret.replace(/^.*\x00/,'')]; this.keybuf = ret.substr(1); @@ -449,7 +459,7 @@ var dk = { main_dir:undefined, gen_dir:undefined, sysop_name:undefined, - default_attr:undefined, + default_attr:new Attribute(7), mode:(js.global.bbs !== undefined && js.global.server !== undefined && js.global.client !== undefined @@ -568,7 +578,7 @@ var dk = { else this.user.ansi_supported = (df[38].toUpperCase === 'Y') ? true : false; this.misc.record_locking = (df[39].toUpperCase === 'N') ? false : true; - this.system.default_attr = new Attribute(parseInt(df[40], 10)); + this.system.default_attr.value = parseInt(df[40], 10); this.user.time_credits = parseInt(df[41], 10); // TODO: Parse a date out of this. this.user.last_new_file_scan_date = df[42];