#define _BSD_SOURCE 1 #include /* for usleep */ #include #include #include #include #include #include #include #include struct PTapUI { PuglView *view; pthread_t thread; LV2UI_Write_Function write; LV2UI_Controller controller; int width; int height; bool exit; }; static void *ui_thread(void *ptr) { PTapUI *pui = (PTapUI *)ptr; while (!pui->exit) { usleep(1000000 / 25); puglProcessEvents(pui->view); } return NULL; } static void parameterChanged(PTapUI *pui, uint32_t index, float value) { pui->write(pui->controller, index, sizeof value, 0, &value); } static void onReshape(PuglView *view, int width, int height) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); glViewport(0, 0, width, height); glOrtho(0, width, height, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glDisable(GL_DEPTH_TEST); glLoadIdentity(); } static void onDisplay(PuglView *view) { PTapUI *pui = (PTapUI *)puglGetHandle(view); glClear(GL_COLOR_BUFFER_BIT); glBegin(GL_QUADS); GLdouble x2 = 2.0; GLdouble y2 = 2.0; GLdouble x1 = pui->width - 2.0; GLdouble y1 = pui->height - 2.0; glColor3f(1.0f, 0.2f, 0.0f); glVertex2f(x1, y1); glVertex2f(x1, y2); glColor3f(0.0f, 1.0f, 0.0f); glVertex2f(x2, x2); glVertex2f(x2, y1); glEnd(); } static void onKeyboard(PuglView *view, bool press, uint32_t key) { } static void onMotion(PuglView *view, int x, int y) { } static void onMouse(PuglView *view, int button, bool press, int x, int y) { } static void onScroll(PuglView *view, float dx, float dy) { } static LV2UI_Handle ptapui_instantiate( const LV2UI_Descriptor *descriptor, const char *plugin_uri, const char *bundle_path, LV2UI_Write_Function write_function, LV2UI_Controller controller, LV2UI_Widget *widget, const LV2_Feature *const *host_features) { PuglNativeWindow parent = 0; LV2UI_Resize *resize = NULL; for (; host_features && *host_features; host_features++) { if (!strcmp((*host_features)->URI, LV2_UI__parent)) { parent = (PuglNativeWindow)(*host_features)->data; } else if (!strcmp((*host_features)->URI, LV2_UI__resize)) { resize = (LV2UI_Resize *)(*host_features)->data; } } if (!parent) { fprintf(stderr, "error: ptapui: No parent window provided.\n"); return NULL; } PTapUI *pui = new PTapUI(); pui->write = write_function; pui->controller = controller; pui->width = 320; pui->height = 240; pui->exit = false; pui->view = puglCreate(parent, "PTap", pui->width, pui->height, true); puglSetHandle(pui->view, pui); puglSetDisplayFunc(pui->view, onDisplay); puglSetReshapeFunc(pui->view, onReshape); puglSetKeyboardFunc(pui->view, onKeyboard); puglSetMotionFunc(pui->view, onMotion); puglSetMouseFunc(pui->view, onMouse); puglSetScrollFunc(pui->view, onScroll); if (resize) { resize->ui_resize(resize->handle, pui->width, pui->height); } pthread_create(&pui->thread, NULL, ui_thread, pui); *widget = (void*)puglGetNativeWindow(pui->view); return pui; } static void ptapui_cleanup(LV2UI_Handle ui) { PTapUI *pui = (PTapUI *)ui; pui->exit = true; pthread_join(pui->thread, NULL); puglDestroy(pui->view); delete pui; } static void ptapui_port_event( LV2UI_Handle ui, uint32_t port_index, uint32_t buffer_size, uint32_t format, const void *buffer) { } static const void *ptapui_extension_data(const char *uri) { return NULL; } static const LV2UI_Descriptor s_lv2uidescriptor = { "urn:fuzzle:ptap#X11UI", &ptapui_instantiate, &ptapui_cleanup, &ptapui_port_event, &ptapui_extension_data, }; const LV2UI_Descriptor *lv2ui_descriptor(uint32_t index) { if (index == 0) { return &s_lv2uidescriptor; } return NULL; }