/* * Print data inside subwindow. Usually data comes from builtin plugin * and/or dynamically loaded plugin. Function is called periodically and * right after cursor movement. */ void pad_draw(void) { void *p; assert(sub_current); dolog("%s: entering\n", __FUNCTION__); if(!main_pad->wd) return; werase(main_pad->wd); sub_current->lines = 0; if(sub_current == &sub_info) { draw_plugin(0); // pad_refresh(); dolog("%s; info only..skipping draw\n", __FUNCTION__); return; } p = on_cursor(); /* handle flags returned by loaded plugin */ if(sub_current->flags & OVERWRITE) draw_plugin(p); else if(sub_current->flags & INSERT) { draw_plugin(p); sub_current->builtin_draw(p); } else if(sub_current->flags & APPEND) { sub_current->builtin_draw(p); draw_plugin(p); } else { dolog("%s; only builtin draw\n", __FUNCTION__); sub_current->builtin_draw(p); } /* number of data lines probably has changed - adjust offset */ if(sub_current->offset + main_pad->size_y - PAD_Y > sub_current->lines) sub_current->offset = sub_current->lines - (main_pad->size_y - PAD_Y); }
void menu::init() { using lifetime = support::action::lifetime; namespace a = support::action::menu; namespace mse = support::action::mouse; auto assetM = engine->get<asset>().lock(); auto act = engine->get<action>().lock(); auto tw = engine->get<tweener<float>>().lock(); assetM->request<polar::asset::audio>("menu1"); font = assetM->get<polar::asset::font>("nasalization-rg"); keep(act->bind<a::down >(lifetime::on, [this] { navigate( 1); })); keep(act->bind<a::up >(lifetime::on, [this] { navigate(-1); })); keep(act->bind<a::right >(lifetime::on, [this] { navigate(0, 1); })); keep(act->bind<a::left >(lifetime::on, [this] { navigate(0, -1); })); keep(act->bind<a::forward>(lifetime::on, [this] { activate(); })); keep(act->bind<a::back >(lifetime::on, [this] { navigate(0, -1, true); })); keep(act->bind<mse::position_y>([this](Decimal y) { if(int(y) != 0) { on_cursor(int(y)); } })); keep(tw->tween(0.0f, 1.0f, 0.25, true, [this](auto, const float &x) { selectionAlpha = x; })); render_all(); }
char *plugin_load(char *file) { void *h; char *err; int i, *type = 0; struct subwin *sb[] = { &sub_proc, &sub_user, &sub_main }; struct subwin *target; AGAIN: if(!(h = dlopen(file, RTLD_LAZY))) { snprintf(dlerr, sizeof dlerr, "%s", dlerror()); return dlerr; } dolog("%s: dlopen returned %x\n", __FUNCTION__, h); /* * Check if the same plugin has been loaded. * Plugin's name could be the same but code could be different. * If so, then probably it has changed so we have to unload it * twice and load again. Ses dlopen(3) for reasons of doing this. */ for(i = 0; i < sizeof sb/sizeof(struct subwin *); i++) { if(sb[i]->handle == h) { dolog("%s: subwin %d has handle %x\n", __FUNCTION__, i, sb[i]->handle); dlclose(h); dlclose(sb[i]->handle); dolog("%s: plugin already loaded in subwin %d, count %d\n", __FUNCTION__, i, i); sb[i]->handle = h = 0; goto AGAIN; break; } } type = dlsym(h, "plugin_type"); if((err = dlerror())) goto ERROR; if(*type >= SUBWIN_NR) { snprintf(dlerr, sizeof dlerr, "Unknown plugin type [%d]", *type); dlclose(h); return dlerr; } target = sb[*type]; target->plugin_init = dlsym(h, "plugin_init"); if((err = dlerror())) goto ERROR; target->plugin_draw = dlsym(h, "plugin_draw"); if((err = dlerror())) goto ERROR; target->plugin_clear = dlsym(h, "plugin_clear"); target->plugin_cleanup = dlsym(h, "plugin_cleanup"); /* close previous library if it was loaded */ if(target->handle) { int i; i = dlclose(target->handle); dolog("%s: closing prev library: %d %s\n", __FUNCTION__, i, dlerror()); } dolog("%s: plugin loaded\n", __FUNCTION__); target->handle = h; target->flags = target->plugin_init(on_cursor()); return 0; ERROR: dolog("%s: plugin not loaded\n", __FUNCTION__); snprintf(dlerr, sizeof dlerr, "%s", err); dlclose(h); return dlerr; }