ref: e7d741e82a935ee6cf079e68f2a8b6856d7f0323
dir: /demo/plan9.c/
#include <u.h> #include <libc.h> #include <draw.h> #include <mouse.h> #include <keyboard.h> #include <thread.h> #include <bio.h> #include "common.h" static Mousectl *mctl; static Keyboardctl *kctl; void threadmain(int argc, char **argv) { Rune key; Mouse m; Alt a[] = { { nil, &m, CHANRCV }, { nil, nil, CHANRCV }, { nil, &key, CHANRCV }, { nil, nil, CHANEND}, }; int oldbuttons, b, nkey, gotevent; char text[5], *s; mu_Command *cmd; mu_Context *ctx; Biobuf *snarf; char *oldcmds; int oldcmdsidx; USED(argc); USED(argv); if (initdraw(nil, nil, "microui demo") < 0) sysfatal("initdraw: %r"); if ((mctl = initmouse(nil, screen)) == nil) sysfatal("initmouse: %r"); if ((kctl = initkeyboard(nil)) == nil) sysfatal("initkeyboard: %r"); a[0].c = mctl->c; a[1].c = mctl->resizec; a[2].c = kctl->c; srand(time(0)); threadsetname("microui demo"); ctx = malloc(sizeof(mu_Context)); mu_init(ctx); ctx->text_width = r_get_text_width; ctx->text_height = r_get_text_height; ctx->style->font = display->defaultfont; r_init(); process_frame(ctx); oldbuttons = 0; oldcmds = malloc(sizeof(ctx->command_list.items)); oldcmdsidx = -1; for (;;) { process_frame(ctx); if (oldcmdsidx != ctx->command_list.idx || memcmp(oldcmds, ctx->command_list.items, oldcmdsidx) != 0) { oldcmdsidx = ctx->command_list.idx; memmove(oldcmds, ctx->command_list.items, oldcmdsidx); cmd = nil; r_clear(mu_color(bg[0], bg[1], bg[2], 255)); while (mu_next_command(ctx, &cmd)) { switch (cmd->type) { case MU_COMMAND_TEXT: r_draw_text(ctx->style->font, cmd->text.str, cmd->text.pos, cmd->text.color); break; case MU_COMMAND_RECT: r_draw_rect(cmd->rect.rect, cmd->rect.color); break; case MU_COMMAND_ICON: r_draw_icon(cmd->icon.id, cmd->icon.rect, cmd->icon.color); break; case MU_COMMAND_CLIP: r_set_clip_rect(cmd->clip.rect); break; } } r_present(); } gotevent = 1; switch (alt(a)) { case 0: /* mouse */ m.xy.x -= screen->r.min.x; m.xy.y -= screen->r.min.y; mu_input_mousemove(ctx, m.xy.x, m.xy.y); if ((b = (m.buttons & 1)) != (oldbuttons & 1)) (b ? mu_input_mousedown : mu_input_mouseup)(ctx, m.xy.x, m.xy.y, MU_MOUSE_LEFT); else if ((b = (m.buttons & 2)) != (oldbuttons & 2)) (b ? mu_input_mousedown : mu_input_mouseup)(ctx, m.xy.x, m.xy.y, MU_MOUSE_MIDDLE); else if ((b = (m.buttons & 4)) != (oldbuttons & 4)) (b ? mu_input_mousedown : mu_input_mouseup)(ctx, m.xy.x, m.xy.y, MU_MOUSE_RIGHT); if (m.buttons == 5 && (snarf = Bopen("/dev/snarf", OREAD)) != nil) { if ((s = Brdstr(snarf, 0, 1)) != nil) { mu_input_text(ctx, s); free(s); } Bterm(snarf); } oldbuttons = m.buttons; break; case 1: /* resize */ getwindow(display, Refnone); oldcmdsidx = -1; break; case 2: /* keyboard */ nkey = -1; switch (key) { case Kdel: goto end; case Kshift: nkey = MU_KEY_SHIFT; break; case Kbs: nkey = MU_KEY_BACKSPACE; break; case '\n': nkey = MU_KEY_RETURN; break; default: if (key < 0xf000 || key > 0xffff) { memset(text, 0, sizeof(text)); if (runetochar(text, &key) > 0) mu_input_text(ctx, text); } break; } if (nkey >= 0) { mu_input_keydown(ctx, nkey); mu_input_keyup(ctx, nkey); } break; default: gotevent = 0; break; } if (gotevent) process_frame(ctx); } end: closemouse(mctl); closekeyboard(kctl); threadexitsall(nil); }