Plan 9 from Bell Labs’s /usr/web/sources/contrib/nemo/octopus/port/mero/omptext.b

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


implement Pimpl;
include "sys.m";
	sys: Sys;
	sprint, fprint: import sys;
include "styx.m";
include "styxservers.m";
	Styxserver: import Styxservers;
include "daytime.m";
include "dat.m";
	dat: Dat;
	mnt, evc, Qdir, debug, appl, slash: import dat;
include "string.m";
	str: String;
	splitl: import str;
include "names.m";
	names: Names;
	dirname: import names;
include "error.m";
	err: Error;
	checkload, panic, stderr: import err;
include "tbl.m";
	tbl: Tbl;
	Table: import tbl;
include "mpanel.m";
	Amax, Panel, Repl, Tappl, Trepl: import Panels;

Aclean, Afont, Asel, Amark, Ascroll, Atab: con Amax + iota;

init(d: Dat): list of string
{
	dat = d;
	sys = dat->sys;
	err = dat->err;
	str = dat->str;
	names = dat->names;
	return list of {"text:", "button:", "label:", "tag:", "tbl:"};
}

pinit(p: ref Panel)
{
	(t, n) := splitl(p.name, ":");
	if (n != nil)
		n = n[1:];
	else
		n = "";
	case t {
	* =>
		p.data = array of byte "";
	"button" or "label" =>
		p.data = array of byte n;
	}
}

rinit(p: ref Panel, r: ref Repl)
{
	(t, nil) := splitl(p.name, ":");
	nfont := "font R";
	case t {
	"tbl" =>
		nfont = "font R";
	"label" or "button" or "tag" =>
		nfont = "font B";
	* =>
		nfont = "font R";
	}
	attrs := array[] of { "clean", nfont, "sel 0 0", "mark 0", "noscroll", "tab 4"};
	nattrs := array[len r.attrs + len attrs] of string;
	nattrs[0:] = r.attrs;
	nattrs[len r.attrs:] = attrs;
	r.attrs = nattrs;
}

newdata(p: ref Panel): string
{
	for (i := 0; i < len p.data; i++)
		if (p.data[i] == byte 0)
			return "UTF 0 not allowed";
	return nil;
}

sel(p: ref Panel, r: ref Repl, args: list of string): (int, string)
{
	n := int hd tl args;
	n2:= int hd tl tl args;
	if (n < 0 || n2 < 0)
		return (0, "negative pos");
	if (n > len p.data)
		n = len p.data;
	if (n2 > len p.data)
		n2 = len p.data;
	r.attrs[Asel] = sprint("sel %d %d", n, n2);
	if (r.id == 0){
		for (rn := 0; rn < len p.repl; rn++)
			if ((pr := p.repl[rn]) != nil)
				pr.attrs[Asel] = r.attrs[Asel];
		return (1, nil);
	} else
		return (0, nil);
}

dirtyclean(p: ref Panel, r: ref Repl, args: list of string): (int, string)
{
	r.attrs[Aclean] = hd args;
	for (rn := 0; rn < len p.repl; rn++)
		if ((pr := p.repl[rn]) != nil)
			pr.attrs[Aclean] = r.attrs[Aclean];
	return (1, nil);
}

font(p: ref Panel, r: ref Repl, args: list of string): (int, string)
{
	fonts := array[] of  { "L", "B", "S", "R", "I", "T" };
	for (x := 0; x < len fonts; x++)
		if (hd tl args == fonts[x])
			break;
	if (x == len fonts)
		return (0, "not a font");
	r.attrs[Afont] = "font " + fonts[x];
	if (r.id == 0){
		for (rn := 0; rn < len p.repl; rn++)
			if ((pr := p.repl[rn]) != nil)
				pr.attrs[Afont] = r.attrs[Afont];
		return (1, nil);
	} else
		return (0, nil);
}

mark(p: ref Panel, r: ref Repl, args: list of string): (int, string)
{
	n := int hd tl args;
	if (n < 0)
		return (0, "negative mark");
	if (n > len p.data)
		n = len p.data;
	r.attrs[Amark] = sprint("mark %d", n);
	if (r.id == 0){
		for (rn := 0; rn < len p.repl; rn++)
			if ((pr := p.repl[rn]) != nil)
				pr.attrs[Amark] = r.attrs[Amark];
		return (1, nil);
	} else
		return (0, nil);
}

tab(p: ref Panel, r: ref Repl, args: list of string): (int, string)
{
	n := int hd tl args;
	if (n < 3 || n > 10)
		return (0, "tab must be in [3:10]");
	r.attrs[Atab] = sprint("tab %d", n);
	if (r.id == 0){
		for (rn := 0; rn < len p.repl; rn++)
			if ((pr := p.repl[rn]) != nil)
				pr.attrs[Atab] = r.attrs[Atab];
		return (1, nil);
	} else
		return (0, nil);
}

# Both ins and del need special update rules. They return (2, *)
# to signal fswrite to update other replicas by sending just the
# ctl data via events, and not by posting update events using the
# conventional rules.
# Also, although we store data as array of byte, positions refer
# to runes. 
# BUG: converting to string and back to array of byte was fine
# for testing, but it's not reasonable. Convert offsets instead.

del(p: ref Panel, nil: ref Repl, args: list of string): (int, string)
{
	pos := int hd tl args;
	n := int hd tl tl args;
	data := string p.data;
	if (pos > len data)
		pos = len data;
	if (pos < 0)
		return (0, "negative pos");
	if (pos + n > len data)
		n = len data - pos;
	if (n == 0)
		return (0, nil);
	if (n < 0)
		return (0, "negative del");
	data = data[0:pos] + data[pos+n:];
	p.data = array of byte data;
	return (2, nil);			# see comment above
}

ins(p: ref Panel, nil: ref Repl, args: list of string): (int, string)
{
	pos := int hd tl args;
	b := hd tl tl args;
	data := string p.data;
	if (pos+1 > len data)
		pos = len data;
	if (pos < 0)
		return (0, "negative pos");
	data = data[0:pos] + b + data [pos:];
	p.data = array of byte data;

	return (2, nil);			# see comment above
}

ctl(p: ref Panels->Panel, r: ref Panels->Repl, ctl: list of string): (int, string)
{
	case hd ctl {
	"clean" or "dirty" =>
		if (len ctl != 1)
			return (0, "no arguments needed");
		return dirtyclean(p, r, ctl);
	"font" =>
		if (len ctl != 2)
			return (0, "1 argument needed");
		return font(p, r, ctl);
	"sel" =>
		if (len ctl != 3)
			return (0, "2 arguments needed");
		return sel(p, r, ctl);
	"mark" =>
		if (len ctl != 2)
			return (0, "1 argument needed");
		return mark(p, r, ctl);
	"ins" =>
		if (len ctl != 3)
			return (0, "2 arguments needed");
		return ins(p, r, ctl);
	"del" =>
		if (len ctl != 3)
			return (0, "2 arguments needed");
		return del(p, r, ctl);
	"tab" =>
		if (len ctl != 2)
			return(0, "1 argument needed");
		return tab(p, r, ctl);
	* =>
		return (0, "not mine");
	}
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.