XXIIVV
Hello Libdraw
Hello Libdraw

Notes on customizing and developing on the Plan 9 operating system.

Collected notes on writing GUI applications and modifying the look and feel of the Plan9 operating system. For a more complete example, see the Plan9 Clock. For more general notes on the C language, see ANSI C.

Plan 9 C Example

#include <u.h>
#include <libc.h>

void
main(void)
{
  print("hello, world\n");
  exits(0);
}

Compilers

To convert source to an executable binary is a two-step process. First run the compiler, 5c, on the source, say file.c, to generate an object file file.5. Then run the loader, 5l, to generate an executable 5.out that may be run(on an ARM machine):

2c file.c
2l file.2 # Or, 2l file file.2
2.out

The loader automatically links with whatever libraries the program needs, usually including the standard C library as defined by libc.h. The compiler does not generate an executable automatically; the output of the compiler must be given to the loader. Since most compilation is done under the control of mk, this is rarely an inconvenience.

compilerlinker
SPARCkcklka
PowerPCqcqlqa
MIPSvcvlva
ARM5c5l5a
AMD646c6l6a
Intel3868c8l8a
PowerPC64bits9c9l9a
RISCVicilia
RISCV64jcjlja

IO

do_output.c

#include <u.h>
#include <libc.h>

void
main(int argc, char **argv)
{
	print("(output)");
}

do_input.c

#include <u.h>
#include <libc.h>

void
main(int argc, char **argv)
{
	int fd;

	if (argc == 1) 
		fd = 0;
	else if ((fd = open(argv[1], OREAD)) < 0) 
		perror(argv[1]);

	char *buf[256];
	read(fd, buf, 256);
	print("(input: %s)\n", buf);
	close(fd);
}

Plan 9 Mouse Example

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

void
eresized(int new)
{
	if(new&& getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
}

void
main(int argc, char* argv[])
{
	USED(argc, argv);

	Mouse m;
	Point prevm;
	initdraw(0, 0, "Example: Mouse");
	eresized(0);
	einit(Emouse);

	/* Main loop */
	for(;;) {
		m = emouse();
		if(m.buttons & 4)
			break;
		if(m.buttons & 1) {
			line(screen,
			     prevm.x == -1 ? m.xy : prevm,
			     m.xy, Enddisc, Enddisc, 1, display->black, ZP);
			prevm = m.xy;
		} else {
			prevm = Pt(-1, -1);
		}
	}
}

Plan 9 Keyboard Example

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>
#include <keyboard.h>

void
eresized(int new)
{
	if(new&& getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
}

void
main(int argc, char* argv[])
{
	USED(argc, argv);

	Event ev;
	int e;
	initdraw(0, 0, "Example: Keyboard");
	eresized(0);
	einit(Ekeyboard);

	/* Main loop */
	for(;;) {
		e = event(&ev);
		if(e == Ekeyboard) {
			print("key: %d\n", ev.kbdc);
			/* Break on escape */
			if(ev.kbdc == 27) {
				print("Escaped\n");
				break;
			}
		}
	}
}

Plan 9 Menu Example

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

char* options1[] = {"Middle Click", "", "Paste", "Snarf", "Exit", 0};
char* options2[] = {"Right Click", "", "Option3", "Option4", "Exit", 0};

Menu middlemenu = {options1};
Menu rightmenu = {options2};

void
eresized(int new)
{
	if(new&& getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
}

void
dopaste(void)
{
	int f;
	if((f = open("/dev/snarf", OREAD)) >= 0) {
		char body[30];
		read(f, body, 30);
		print("Paste: %s\n", body);
		close(f);
	}
}

void
dosnarf(void)
{
	int f;
	if((f = open("/dev/snarf", OWRITE)) >= 0) {
		char* body = "some text";
		write(f, body, strlen(body));
		print("Snarf: %s\n", body);
		close(f);
	}
}

void
main(int argc, char* argv[])
{
	USED(argc, argv);

	Event ev;
	int e;

	initdraw(0, 0, "Example: Menu");
	eresized(0);
	einit(Emouse);

	/* Main event loop */
	for(;;) {
		e = event(&ev);
		/* Middle Click */
		if((e == Emouse) && (ev.mouse.buttons & 3)) {
			if(emenuhit(2, &ev.mouse, &middlemenu) == 2)
				dopaste();
			if(emenuhit(2, &ev.mouse, &middlemenu) == 3)
				dosnarf();
			if(emenuhit(2, &ev.mouse, &middlemenu) == 4)
				exits(nil);
		}
		/* Right Click */
		else if((e == Emouse) && (ev.mouse.buttons & 4)) {
			if(emenuhit(3, &ev.mouse, &rightmenu) == 2)
				print("Pressed Option 3\n");
			if(emenuhit(3, &ev.mouse, &rightmenu) == 3)
				print("Pressed Option 4\n");
			if(emenuhit(3, &ev.mouse, &rightmenu) == 4)
				exits(nil);
		}
	}
}

Plan 9 Drawing Example

#include <u.h>
#include <libc.h>
#include <draw.h>
#include <event.h>

void
eresized(int new)
{
	if(new&& getwindow(display, Refnone) < 0)
		sysfatal("can't reattach to window");
}

void
main(int argc, char* argv[])
{
	USED(argc, argv);
	
	Mouse m;
	Point o;
	int pad, size;

	initdraw(0, 0, "Example: Primitives");
	eresized(0);
	einit(Emouse);

	pad = 20;
	size = 100;
	o = screen->r.min;

	draw(screen,
	     Rect(o.x + pad, o.y + pad, o.x + pad + size, o.y + pad + size),
	     display->black, nil, ZP);
	string(screen,
	       Pt(o.x + pad, o.y + pad + size),
	       display->black, ZP, display->defaultfont, "draw");

	fillellipse(screen,
	            Pt(o.x + pad + size * 1.5, o.y + pad + size / 2),
	            size / 2, size / 2, display->black, ZP);
	string(screen,
	       Pt(o.x + pad + size, o.y + pad + size),
	       display->black, ZP, display->defaultfont, "fillellipse");

	fillarc(screen,
	        Pt(o.x + pad + size * 2, o.y + pad + size),
	        size, size, display->black, ZP, 0, 90);
	string(screen,
	       Pt(o.x + pad + size * 2, o.y + pad + size),
	       display->black, ZP, display->defaultfont, "fillarc");

	line(screen,
	     Pt(o.x + pad, o.y + pad * 2 + size),
	     Pt(o.x + pad + size, o.y + pad * 2 + size * 2),
	     Endsquare, Endsquare, 0, display->black, ZP);
	string(screen,
	       Pt(o.x + pad, o.y + pad * 2 + size * 2),
	       display->black, ZP, display->defaultfont, "line");

	ellipse(screen,
	        Pt(o.x + pad + size * 1.5, o.y + pad * 2 + size * 1.5),
	        50, 50, 0, display->black, ZP);
	string(screen,
	       Pt(o.x + pad + size, o.y + pad * 2 + size * 2),
	       display->black, ZP, display->defaultfont, "ellipse");

	arc(screen,
	    Pt(o.x + pad + size * 2, o.y + pad * 2 + size * 2),
	    size, size, 0, display->black, ZP, 1, 90);
	string(screen,
	       Pt(o.x + pad + size * 2, o.y + pad * 2 + size * 2),
	       display->black, ZP, display->defaultfont, "arc");

	/* Main loop */
	for(;;) {
		m = emouse();
		if(m.buttons & 4)
			break;
	}
}
Plan9 Draw
Plan9 Draw

incoming moogle ansi c plan9 plan9 clock plan9 color