#include #include #include #include "../wordwrap.h" #include "slideshow.h" /* We use the font set by initdraw() for most things, but can set our own.. */ Font *titlefont, *smallfont; void content_init(void); /* Initialization, mostly for additional fonts. */ void loadfonts(void) { char *service; service = getenv("service"); if (!service || ((strcmp(service, "unix") == 0) || strcmp(service, "") == 0)) titlefont = openfont(display, "/mnt/font/Cochin/56a/font"); else titlefont = openfont(display, "/lib/font/bit/lucida/unicode.28.font"); if (!service || ((strcmp(service, "unix") == 0) || strcmp(service, "") == 0)) smallfont = openfont(display, "/mnt/font/Cochin/40a/font"); else smallfont = openfont(display, "/lib/font/bit/lucida/unicode.18.font"); if (titlefont == nil) { fprint(2, "%s: openfont failed: %r\n", argv0); exits("openfont"); } } void xblank(void) { Point p; draw(screen, screen->r, background, nil, ZP); p = stringsize(font, "X"); p = Pt(screen->r.max.x - p.x*2, screen->r.max.y - p.y*2); string(screen, p, display->black, ZP, font, "X"); } void xblankreset(void) { xblank(); reset(); } void hello(void) { Point p; char* t0 = "Welcome to Plan 9"; char* name = "Anthony Sorace"; char* email = "a@9srv.net"; insert = Pt((screen->r.min.x + margin), (screen->r.min.y + margin)); insert = wrline(titlefont, t0); p = stringsize(font, name); insert = Pt(screen->r.max.x - margin*2 - p.x, screen->r.max.y - margin*0.5 - p.y*2); insert = wrline(font, name); p = stringsize(font, email); insert = Pt(screen->r.max.x - margin*2 - p.x, screen->r.max.y - margin*0.5 - p.y); insert = wordwrap(screen, insert, display->black, ZP, font, email, margin); } void toc(void) { char* head = "Hello from Plan 9!"; char* body[] = { "What is it?", // "Where did it come from?", "Why is it interesting?", "A quick(ish) tour.", "Why you might (or might not) want to try it.", "Where are we now?", nil, }; head_body(font, head, body); } void intro(void) { char* head = "What is Plan 9?"; char* body[] = { "A Unix-inspired general-purpose operating system.", "Good for lots of things, from supercomputers to embedded systems.", "Designed in the same lab at Bell Labs as Unix.", "With 20 years of extra experience.", "How to address “novel” things that are bolted-on in Unix.", "“Novel” like graphics and networking.", nil, }; head_body_stepwise(font, head, body); insert = newline(smallfont, insert); } void problems_quote(void) { char* q = "“The problems with UNIX were too deep to fix, " "but some of its ideas could be brought along. " "The best was its use of the file system to coordinate " "naming of and access to resources, even those, " "such as devices, not traditionally treated as files.”"; insert = wordwrap(screen, insert, display->black, ZP, smallfont, q, margin); } void history_dates(void) { char* head = "History (boring dates)"; char* body[] = { "1989: first papers", "1992: 1st Edition", "1995: 2nd Edition", "2000: 3rd Edition (open source)", "2002: 4th Edition (OSI-approved open source)", "2015: Final 4th Edition release from Bell Labs", "", "...and a bunch of other stuff happened.", nil, }; head_body(font, head, body); } void interesting(void) { int omargin = margin; insert = wrline(font, "Why is it interesting?"); insert = newline(font, insert); margin = margin*2; insert = wrline(font, "Plan 9 is organized around three principles:"); insert = wrline(font, "→ “Everything is a file.”"); insert = wrline(font, "→ 9p is used for all access."); insert = wrline(font, "→ Processes get—and can manipulate—their own namespaces."); margin = omargin; insert = newline(font, insert); insert = wrline(font, "The power in the system comes from consistently applying those ideas."); } void interesting_reset(void) { char* head = "But wait, there's more!"; char * body[] = { "Take the opportunity to reset the userspace.", "Lots of familiar tools in unix get rethought.", "'make' → 'mk', 'sh' → 'rc'...", "Lots of others get cleaned up.", "New tools for common functions:", "upas for mail, acme as your editor/IDE, &c", nil, }; head_body_stepwise(font, head, body); } void interesting_compilers(void) { char* head = "Cross-compilation is trivial here."; char * body[] = { "Cross-compilation on unix is *awful*.", "Cross-compilation might be more common than ever...", "...and they didn't make it better.", "'objtype=arm mk all'", "New compilers helped a lot, but it's really the system layout.", nil, }; head_body_stepwise(font, head, body); } void outcomes(void) { char* head = "Some interesting output:"; char* body[] = { "UTF-8", "/proc", "rfork()/clone()", "namespaces (e.g. Docker)", "", "(partial credit)", "Porter-Duff compositing", "CSP", nil, }; head_body_stepwise(font, head, body); } void tour(void) { Point center, w; char* t = "Okay, let's look around."; center = addpt(screen->r.min, Pt((screen->r.max.x - screen->r.min.x)/2, (screen->r.max.y - screen->r.min.y)/2)); w = stringsize(font, t); insert = subpt(center, Pt(w.x/2, w.y/2)); string(screen, insert, display->black, ZP, font, t); } void why_not(void) { char* head = "Why you might want to try it."; char* body[] = { "WARNING!", "It (probably) doesn't have (most of) the programs you want.", "It doesn't (really) have a web browser.", "Hardware support is spotty.", "It's unlikely to get you a job (directly).", nil, }; head_body_stepwise(font, head, body); } void why(void) { char* head = "Why you might still want to try it."; char* body[] = { "Y'all look like brave souls...", "It's a great example of how to consistently apply an organizing principle.", "That matters for how it feels to use the system.", "You can understand all the parts.", "You can understand how they fit together.", nil, }; head_body_stepwise(font, head, body); } void today(void) { Point center, w; char* t = "Where are we now?"; center = addpt(screen->r.min, Pt((screen->r.max.x - screen->r.min.x)/2, (screen->r.max.y - screen->r.min.y)/2)); w = stringsize(font, t); insert = subpt(center, Pt(w.x/2, w.y/2)); string(screen, insert, display->black, ZP, font, t); } void distros(void) { insert = wrline(font, "Pick your Plan 9!"); insert = newline(font, insert); insert = wrline(font, "9legacy"); insert.x = insert.x + margin; insert = wrline(smallfont, "The most like a “4.5”; 4 + lots of patches."); insert = wrline(font, "9front"); insert.x = insert.x + margin; insert = wrline(smallfont, "The most active."); insert = wrline(font, "Nix"); insert.x = insert.x + margin; insert = wrline(smallfont, "No, not that nix."); insert.x = insert.x + margin; insert = wrline(smallfont, "Add “applicaiton cores”. The most researchy."); insert = newline(font, insert); insert = wrline(smallfont, "Several other dormant or defunct ones: 9atom, Havey, Akeros, others."); insert = wrline(smallfont, "Also, all the Bell Labs releases under an MIT license now."); } void howto(void) { char* head = "Hardware support isn't *that* bad..."; char* body[] = { "All Raspberries Pi before the 5 & 500.", "9front is doing a great job with PCs, especially thinkpads.", "VM & VPS support is very good.", "Small but growing list of risc-v platfoms.", "Kirkwood! Brightstar! ...Alpha?", nil, }; head_body_stepwise(font, head, body); } void p9p(void) { char* head = "There's also Plan 9 from User Space."; char* body[] = { "A port of much of Plan 9's user space to unix-like systems.", "Libraries (e.g. libthread, lib9p) and utilities (rc! acme!).", "9p client for talking to Plan 9.", "No real namespaces, doesn't fix (or try to) Unix's real issues.", nil, }; head_body(font, head, body); } void p9f(void) { char* head = "Plan 9 Foundation"; char* body[] = { "Founded in 2021.", "Wanted to re-start the International Workshop on Plan 9.", "Got Nokia to give us the copyright.", "Re-licensed everything under MIT.", "Re-started the International Workshop on Plan 9.", "Happened in 2023, 2024, 2025... come to UVic in May!", "501(c)(3) in the US.", nil, }; head_body_stepwise(font, head, body); } void more(void) { char* head = "Where to learn more:"; char * body[] = { "Web: p9f.org", "Mailing list: 9fans.topicbox.com", "IRC: #plan9 on libera.chat", "", "9legacy: 9legacy.org", "9front: 9front.org", "plan9port: 9fans.github.io/plan9port/", nil, }; head_body(font, head, body); } void thanks(void) { int i; Point center, w; char* thanks = "Thank you! ☺"; char* f[] = { "Plan 9: http://p9f.org", "IWP9: http://iwp9.org", // "Presentation: http://a.9srv.net/src/slideshow", nil, }; center = addpt(screen->r.min, Pt((screen->r.max.x - screen->r.min.x)/2, (screen->r.max.y - screen->r.min.y)/3)); w = stringsize(font, thanks); insert = subpt(center, Pt(w.x/2, w.y/2)); string(screen, insert, display->black, ZP, font, thanks); insert = newline(font, insert); insert = newline(font, insert); for(i=0; f[i] != nil; i++) { w = stringsize(smallfont, f[i]); insert.x = screen->r.min.x + (screen->r.max.x - screen->r.min.x)/2 - w.x/2; // insert = Pt(screen->r.mix.x + w.x/2, insert.y); insert = wordwrap(screen, insert, display->black, ZP, smallfont, f[i], margin); insert = newline(font, insert); } } Step steptab[] = { {content_init, hello, nil, nil}, {blankreset, toc, nil, nil}, /* What is it? */ {blankreset, intro, nil, nil}, // /* Where did it come from? */ // {blankreset, history, page_end, nil}, {nil, problems_quote, page_end, nil}, {blankreset, history_dates, page_end, nil}, /* Why is it interesting? */ {blankreset, interesting, page_end, nil}, {blankreset, interesting_reset, page_end, nil}, {blankreset, outcomes, page_end, nil}, /* A quick(ish) tour. */ {blankreset, tour, page_end, nil}, /* Why you might (or might not) want to try it. */ {blankreset, why_not, page_end, nil}, {blankreset, why, page_end, nil}, /* Where are we now? */ {blankreset, today, page_end, nil}, {blankreset, howto, page_end, nil}, {blankreset, distros, page_end, nil}, {blankreset, p9p, page_end, nil}, {blankreset, p9f, page_end, nil}, {blankreset, more, page_end, nil}, /* The end. */ {blankreset, thanks, page_end, nil}, }; /* Last becuase we need steptab already initialized. */ void content_init(void) { margin = 100; blank(); reset(); nsteps = sizeof(steptab)/sizeof(Step); loadfonts(); }