#include #include #include #include #include #include #include "nk.h" #include "exec.h" int mainstacksize = 32*1024; typedef struct VM VM; struct VM { int pid; int running; char msg[128]; VM* next; }; static VM vm1; static void mainmenu(struct nk_context *ctx) { struct nk_color col; float wid; char buf[256]; VM *vm; vm = &vm1; if(nk_begin(ctx, "mainmenu", nk_rect(0, 0, Dx(screen->r), Dy(screen->r)), NK_WINDOW_BORDER|NK_WINDOW_NO_SCROLLBAR|NK_WINDOW_BACKGROUND)){ //nk_menubar_begin(ctx); static int mb = 64; static const char *resolutions[] = { "640x480", "800x600", "1024x768" }; static int resolution = 0; static int networking = 1; nk_layout_row_static(ctx, 30, 100, 2); nk_label(ctx, "Memory:", NK_TEXT_LEFT); mb = nk_propertyi(ctx, "#MB", 64, mb, 8192, 1, 8); nk_layout_row_static(ctx, 30, 100, 2); nk_label(ctx, "Resolution:", NK_TEXT_LEFT); resolution = nk_combo(ctx, resolutions, nelem(resolutions), resolution, 25, nk_vec2(100,200)); nk_layout_row_static(ctx, 30, 100, 1); nk_checkbox_label(ctx, "Networking", &networking); nk_layout_row_begin(ctx, NK_STATIC, 30, 2); nk_layout_row_push(ctx, 30); if(vm->running == 0){ if(nk_button_symbol(ctx, NK_SYMBOL_TRIANGLE_RIGHT)){ vm->pid = spawn("/bin/vmx -M %dM -v %s %s /amd64/9pc64", mb, resolutions[resolution], networking ? "-n /net/ether0" : ""); if(vm->pid < 0) snprint(vm->msg, sizeof(vm->msg), "launch error: %r"); else vm->running = 1; } } else if(nk_button_symbol(ctx, NK_SYMBOL_RECT_SOLID)){ if(postnote(PNGROUP, vm->pid, "kill") < 0) rerrstr(vm->msg, sizeof(vm->msg)); } wid = nk_widget_width(ctx); if(vm->running == 0 && vm->pid > 0){ if(vm->msg[0] != 0) col = nk_rgb(255, 0, 0); else col = nk_rgb(255, 255, 0); snprint(buf, sizeof(buf), "Process %d exited: %s", vm->pid, vm->msg[0] ? vm->msg : ""); } else if(vm->running == 1 && vm->pid > 0) { col = nk_rgb(0, 255, 0); snprint(buf, sizeof(buf), "Process %d running", vm->pid); } else { col = nk_rgb(255, 255, 0); snprint(buf, sizeof(buf), "pid=%d running=%d msg=%s", vm->pid, vm->running, vm->msg); } nk_layout_row_push(ctx, strlen(buf)*wid); nk_label_colored(ctx, buf, NK_TEXT_LEFT, col); nk_layout_row_end(ctx); //nk_menubar_end(ctx); } nk_end(ctx); } static void nkthread(void*) { nkinit(mainmenu); } static void usage(void) { fprint(2, "usage: %s\n", argv0); threadexitsall("usage"); } void threadmain(int argc, char *argv[]) { Channel *waitchan; Waitmsg *waitmsg; VM *vm = &vm1; ARGBEGIN{ default: usage(); }ARGEND waitchan = threadwaitchan(); threadcreate(nkthread, nil, 8192); enum { AWAIT, AEND }; Alt alts[] = { [AWAIT] { waitchan, &waitmsg, CHANRCV }, [AEND] { nil, nil, CHANEND }, }; for(;;){ switch(alt(alts)){ case AWAIT: if(waitmsg->pid == vm->pid){ vm->running = 0; strcpy(vm->msg, waitmsg->msg); } free(waitmsg); break; } } }