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.
compiler | linker | ||
SPARC | kc | kl | ka |
PowerPC | qc | ql | qa |
MIPS | vc | vl | va |
ARM | 5c | 5l | 5a |
AMD64 | 6c | 6l | 6a |
Intel386 | 8c | 8l | 8a |
PowerPC64bits | 9c | 9l | 9a |
RISCV | ic | il | ia |
RISCV64 | jc | jl | ja |
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; } }
incoming moogle ansi c plan9 plan9 clock plan9 color