Sigrid Solveig Haflínudóttirfix a few warningseea0bd91 year agoHistory
1756 lines · 36.3 KB · C
RawDownload
#include "plan9.h"#include "field.h"#include "gbuffer.h"#include "sim.h"#include <bio.h>#include <draw.h>#include <mouse.h>#include <keyboard.h>#include <thread.h>#include <plumb.h>#include <cursor.h>#include <tos.h>#include "theme.h" #define MIN(x,y) ((x)<=(y)?(x):(y))#define MAX(x,y) ((x)>=(y)?(x):(y))#define is_movement(c) (c == 'W' || c == 'N' || c == 'E' || c == 'S')#define is_send(c) (c == ':' || c == '%' || c == '!' || c == '?' || c == ';' || c == ';' || c == '$') enum {	Txtoff = 16,	Coloff = 2, 	Cresize = 0,	Ckey,	Cmouse,	Credraw,	Numchan, 	Sfancy = 0,	Splain,	Snone,	Numstyles, 	Minsert = 0,	Mappend,	Mslide,	Mselect,	Nummodes, 	Menu3load = 0,	Menu3save,	Menu3dotstyle,	Menu3rulerstyle,	Menu3colors,	Menu3exit,	Nummenu3, 	/* this might become a bad idea in the future */	Mark_flag_group_highlight = 1<<6,	Mark_flag_selected = 1<<7, 	Midicn = 0<<4, /* cable number. FIXME: write midifs */}; typedef struct Snap Snap; struct Snap {	int bpm, apm;	vlong tick;	Point cur, scroll;	Rectangle sel;	Field field;}; static int bpm = 120, apm = 120;static Point rulers = {8, 8};static int rulerstyle = Sfancy, dotstyle = Sfancy; static char *ip, *udpport;static int udp = -1; static char *midipath;static int midi = -1;static u8int noteoff[16][128]; /* 16 channels, 128 notes each */ static Help help;static Rune *linebuf;static Rune cursor = '@';static vlong tick;static Point glyphsz;static Point cur, scroll, txtoff, move = { .x = 1, .y = 1 };static Rectangle sel;static Field field;static Mbuf_reusable mbuf, mscr;static char filename[256];static Field fscr, fsel;static bool altdown, shiftdown, ctldown, pause, forward;static int mode = Minsert;static long framedev; /* frame deviation in ms */static char *shellcmd;static bool usensec; static Snap *snaps;static int numsnaps, nextsnap;static int maxsnaps = 100; static Cursor yousure = {	{0, 0},	{ 0xf7, 0xfe, 0x15, 0x54, 0x1d, 0x54, 0x09, 0x54,	  0x09, 0xdc, 0x00, 0x00, 0x75, 0x77, 0x45, 0x54,	  0x75, 0x66, 0x15, 0x54, 0x77, 0x57, 0x00, 0x00,	  0x00, 0x02, 0x2a, 0x84, 0x11, 0x28, 0x2a, 0x90,	},	{ 0xea, 0x2b, 0xea, 0xab, 0xe2, 0xab, 0xf6, 0xab,	  0xf6, 0x23, 0xff, 0xff, 0x8a, 0x88, 0xba, 0xab,	  0x8a, 0x99, 0xea, 0xab, 0x88, 0xa8, 0xff, 0xff,	  0xff, 0xfd, 0xd5, 0x7b, 0xee, 0xd7, 0xd5, 0x6f,	},}; static struct {	struct {		char *menu;		Rune r;	}dot;	struct {		char *menu;		Rune r[9];	}ruler;}styles[Numstyles] = {	[Sfancy] = {		.dot = {"fancy dots", L'·'},		.ruler = {"fancy rulers", {L'╭', L'┬', L'╮', L'├', L'┼', L'┤', L'╰', L'┴', L'╯'}},	},	[Splain] = {		.dot = {"plain dots", '.'},		.ruler = {"plain rulers", {'+', '+', '+', '+', '+', '+', '+', '+', '+'}},	},	[Snone] = {		.dot = {"no dots", ' '},		.ruler = {"no rulers", {0}},	},}; static char *modes[Nummodes] = {	[Minsert] = "insert",	[Mappend] = "append",	[Mslide]  = "slide ",	[Mselect] = "select",}; static char *menu3i[Nummenu3+1] = {	[Menu3load]   = "load",	[Menu3save]   = "save",	[Menu3colors] = "colors",	[Menu3exit]   = "exit",}; static Menu menu3 = {	.item = menu3i,}; static voidsnapshot(void){	Snap *s;	int i; 	if (maxsnaps < 1)		return; 	if (nextsnap >= maxsnaps) {		nextsnap--;		field_deinit(&snaps->field);		memmove(snaps, snaps+1, sizeof(Snap)*nextsnap);	}	s = &snaps[nextsnap++];	s->bpm = bpm;	s->apm = apm;	s->tick = tick;	s->cur = cur;	s->scroll = scroll;	s->sel = sel;	for (i = nextsnap; i < numsnaps; i++)		field_deinit(&snaps[i].field);	field_init(&s->field);	field_copy(&field, &s->field);	numsnaps = nextsnap;} static voidgotosnapshot(int i){	Snap *s; 	s = &snaps[i];	bpm = s->bpm;	apm = s->apm;	tick = s->tick;	cur = s->cur;	scroll = s->scroll;	sel = s->sel;	field_copy(&s->field, &field);} static voidundo(void){	if (nextsnap < 1)		return; 	if (nextsnap == numsnaps) {		snapshot();		nextsnap--;	}	gotosnapshot(--nextsnap);} static voidredo(void){	if (nextsnap >= numsnaps-1)		return; 	gotosnapshot(++nextsnap);	if (nextsnap == numsnaps)		nextsnap--;} Uszorca_round_up_power2(Usz x){	x -= 1;	x |= x >> 1;	x |= x >> 2;	x |= x >> 4;	x |= x >> 8;	x |= x >> 16;	return x + 1;} boolorca_is_valid_glyph(Glyph c){	if (c >= '0' && c <= '9')		return true;	if (c >= 'A' && c <= 'Z')		return true;	if (c >= 'a' && c <= 'z')		return true;	switch (c) {	case '!':	case '#':	case '%':	case '*':	case '.':	case ':':	case ';':	case '=':	case '?':	case '$':		return true;	}	return false;} static Glyphfieldget(int x, int y){	if (x < field.width && y < field.height && x >= 0 && y >= 0)		return field.buffer[x + field.width*y]; 	return 0;} static voidfieldset(int x, int y, Glyph c){	if (x < field.width && y < field.height && x >= 0 && y >= 0)		field.buffer[x + field.width*y] = c;} static voidfieldsetn(int x, int y, Glyph c, int n){	if (y >= 0 && y < field.height) {		for (; n > 0 && x < field.width; n--, x++)			field.buffer[x + field.width*y] = c;	}} static voidselpasteb(Biobuf *b){	char *s;	int cols, rows, i, n, off;	Glyph c; 	for (cols = rows = 0; (s = Brdstr(b, '\n', 1)) != nil;) {		if ((n = Blinelen(b)) > cols)			cols = MIN(n, field.width-sel.min.x);		if (sel.min.y+rows < field.height) {			off = sel.min.x + field.width*(sel.min.y+rows);			for (i = 0; i < MIN(n, field.width-sel.min.x); i++) {				c = orca_is_valid_glyph(s[i]) ? s[i] : '.';				if (c != '.' || !shiftdown)					field.buffer[off+i] = c;			}			rows++;		}		free(s);	}	sel.max.x = sel.min.x + MAX(0, cols-1);	sel.max.y = sel.min.y + MAX(0, rows-1);	if (sel.max.x < cur.x)		cur.x = sel.max.x;	if (sel.max.y < cur.y)		cur.y = sel.max.y;} static voidrunshell(void *x){	int *p; 	p = x;	dup(p[0], 0); close(p[0]); close(p[1]);	dup(p[3], 1); close(p[3]); close(p[2]);	dup(open("/dev/null", OWRITE), 2);	procexecl(nil, "/bin/rc", "rc", "-c", shellcmd, nil);	threadexits("exec: %r");} static voidshellpipe(char *s){	Biobuf *in, *out;	int x, y, p[4];	Glyph g; 	shellcmd = s+1;	pipe(p);	pipe(p+2);	procrfork(runshell, p, 4096, RFFDG);	close(p[0]);	close(p[3]);	out = Bfdopen(p[1], OWRITE);	in = Bfdopen(p[2], OREAD);	for (y = sel.min.y; *s != '<' && y <= sel.max.y; y++) {		for (x = sel.min.x; x <= sel.max.x; x++) {			if ((g = fieldget(x, y)) == '.')				g = ' ';			Bputc(out, g);		}		Bputc(out, '\n');	}	Bterm(out);	if (*s != '>')		selpasteb(in);	Bterm(in);} static voidmidiopen(char *path){	if (midi >= 0) {		close(midi);		midi = -1;	}	if (path != nil) {		free(midipath);		midipath = strdup(path);	}	if (midi < 0 && midipath[0] && (midi = open(midipath, OWRITE)) < 0) {		fprint(2, "midi failed: %r\n");		/* FIXME display error */	}} static voidnetdial(char *newip, char *newudpport){	if (udp >= 0) {		close(udp);		udp = -1;	}	if (newip != nil) {		free(ip);		ip = strdup(newip);	}	if (newudpport != nil) {		free(udpport);		udpport = strdup(newudpport);	} 	if (udp < 0 && ip[0] && udpport[0]) {		if (udpport[0] == '/')			udp = open(udpport, OWRITE);		else			udp = dial(netmkaddr(ip, "udp", udpport), nil, nil, nil); 		if (udp < 0) /* FIXME display error */			fprint(2, "udp failed: %r\n");	}} static voidselset(Rune key){	int y;	bool commented; 	if (key == '#') {		commented = true;		for (y = sel.min.y; y <= sel.max.y && commented; y++)			commented = fieldget(sel.min.x, y) == key && fieldget(sel.max.x, y) == key;		if (commented)			key = '.';	} else {		commented = false;	} 	for (y = sel.min.y; y <= sel.max.y; y++) {		if (key == '#' || commented) {			fieldset(sel.min.x, y, key);			fieldset(sel.max.x, y, key);		} else {			fieldsetn(sel.min.x, y, key, Dx(sel)+1);		}	}} static voidselcopy(void){	Biobuf *b;	int y; 	if ((b = Bopen("/dev/snarf", OWRITE)) != nil) {		for (y = sel.min.y; y <= sel.max.y; y++) {			Bwrite(b, &field.buffer[sel.min.x + field.width*y], Dx(sel)+1);			Bputc(b, '\n');		}		Bterm(b);	}} static voidinject(char *filename){	Biobuf *b; 	if ((b = Bopen(filename, OREAD)) != nil) {		selpasteb(b);		Bterm(b);	}} static voidnosnapshot(void){} static Pointptclamp(Point p){	p.x = MAX(0, MIN((int)field.width-1, p.x));	p.y = MAX(0, MIN((int)field.height-1, p.y));	return p;} static voidcurmove(int x, int y){	Point xy; 	xy = Pt(x, y);	cur = ptclamp(addpt(cur, xy));	sel.min = ptclamp(addpt(sel.min, xy));	sel.max = ptclamp(addpt(sel.max, xy));} static voidselext(int xdt, int ydt){	if (sel.max.x > cur.x || (sel.min.x == cur.x && xdt > 0))		sel.max.x = MAX(sel.max.x+xdt, sel.min.x);	else		sel.min.x = MIN(sel.min.x+xdt, sel.max.x); 	if (sel.max.y > cur.y || (sel.min.y == cur.y && ydt > 0))		sel.max.y = MAX(sel.max.y+ydt, sel.min.y);	else		sel.min.y = MIN(sel.min.y+ydt, sel.max.y); 	rectclip(&sel, Rect(0, 0, (int)field.width-1, (int)field.height-1));} /* * nsec() is wallclock and can be adjusted by timesync * so need to use cycles() instead, but fall back to * nsec() in case we can't */uvlongnanosec(void){	static uvlong fasthz, xstart;	uvlong x, div; 

Lines 1–500 of 1756.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t