175 lines
3.8 KiB
C
175 lines
3.8 KiB
C
#define _BSD_SOURCE 1
|
|
#include <unistd.h> /* for usleep */
|
|
|
|
#include <pthread.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <lv2.h>
|
|
#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>
|
|
#include <pugl/pugl.h>
|
|
|
|
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)
|
|
{
|
|
struct ptapui *pui = (struct ptapui *)ptr;
|
|
while (!pui->exit) {
|
|
usleep(1000000 / 25);
|
|
puglProcessEvents(pui->view);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
static void parameterChanged(struct 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)
|
|
{
|
|
struct ptapui *pui = (struct 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;
|
|
}
|
|
|
|
struct ptapui *pui = malloc(sizeof *pui);
|
|
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)
|
|
{
|
|
struct ptapui *pui = (struct ptapui *)ui;
|
|
pui->exit = true;
|
|
pthread_join(pui->thread, NULL);
|
|
puglDestroy(pui->view);
|
|
free(ui);
|
|
}
|
|
|
|
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 =
|
|
{
|
|
.URI = "urn:fuzzle:ptap#X11UI",
|
|
.instantiate = &ptapui_instantiate,
|
|
.cleanup = &ptapui_cleanup,
|
|
.port_event = &ptapui_port_event,
|
|
.extension_data = &ptapui_extension_data,
|
|
};
|
|
|
|
const LV2UI_Descriptor *lv2ui_descriptor(uint32_t index)
|
|
{
|
|
if (index == 0) {
|
|
return &s_lv2uidescriptor;
|
|
}
|
|
|
|
return NULL;
|
|
}
|