Commit 83ad99f5 authored by Hanspeter Portner's avatar Hanspeter Portner

remove sandbox_ui dir.

parent ef984c68
/*
LV2 External UI extension
This work is in public domain.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
If you have questions, contact Filipe Coelho (aka falkTX) <falktx@falktx.com>
or ask in #lad channel, FreeNode IRC network.
*/
/**
@file lv2_external_ui.h
C header for the LV2 External UI extension <http://kxstudio.sf.net/ns/lv2ext/external-ui>.
*/
#ifndef LV2_EXTERNAL_UI_H
#define LV2_EXTERNAL_UI_H
#include "lv2/lv2plug.in/ns/extensions/ui/ui.h"
#define LV2_EXTERNAL_UI_URI "http://kxstudio.sf.net/ns/lv2ext/external-ui"
#define LV2_EXTERNAL_UI_PREFIX LV2_EXTERNAL_UI_URI "#"
#define LV2_EXTERNAL_UI__Host LV2_EXTERNAL_UI_PREFIX "Host"
#define LV2_EXTERNAL_UI__Widget LV2_EXTERNAL_UI_PREFIX "Widget"
/** This extension used to be defined by a lv2plug.in URI */
#define LV2_EXTERNAL_UI_DEPRECATED_URI "http://lv2plug.in/ns/extensions/ui#external"
#ifdef __cplusplus
extern "C" {
#endif
/**
* When LV2_EXTERNAL_UI__Widget UI is instantiated, the returned
* LV2UI_Widget handle must be cast to pointer to LV2_External_UI_Widget.
* UI is created in invisible state.
*/
typedef struct _LV2_External_UI_Widget {
/**
* Host calls this function regulary. UI library implementing the
* callback may do IPC or redraw the UI.
*
* @param _this_ the UI context
*/
void (*run)(struct _LV2_External_UI_Widget * _this_);
/**
* Host calls this function to make the plugin UI visible.
*
* @param _this_ the UI context
*/
void (*show)(struct _LV2_External_UI_Widget * _this_);
/**
* Host calls this function to make the plugin UI invisible again.
*
* @param _this_ the UI context
*/
void (*hide)(struct _LV2_External_UI_Widget * _this_);
} LV2_External_UI_Widget;
#define LV2_EXTERNAL_UI_RUN(ptr) (ptr)->run(ptr)
#define LV2_EXTERNAL_UI_SHOW(ptr) (ptr)->show(ptr)
#define LV2_EXTERNAL_UI_HIDE(ptr) (ptr)->hide(ptr)
/**
* On UI instantiation, host must supply LV2_EXTERNAL_UI__Host feature.
* LV2_Feature::data must be pointer to LV2_External_UI_Host.
*/
typedef struct _LV2_External_UI_Host {
/**
* Callback that plugin UI will call when UI (GUI window) is closed by user.
* This callback will be called during execution of LV2_External_UI_Widget::run()
* (i.e. not from background thread).
*
* After this callback is called, UI is defunct. Host must call LV2UI_Descriptor::cleanup().
* If host wants to make the UI visible again, the UI must be reinstantiated.
*
* @note When using the depreated URI LV2_EXTERNAL_UI_DEPRECATED_URI,
* some hosts will not call LV2UI_Descriptor::cleanup() as they should,
* and may call show() again without re-initialization.
*
* @param controller Host context associated with plugin UI, as
* supplied to LV2UI_Descriptor::instantiate().
*/
void (*ui_closed)(LV2UI_Controller controller);
/**
* Optional (may be NULL) "user friendly" identifier which the UI
* may display to allow a user to easily associate this particular
* UI instance with the correct plugin instance as it is represented
* by the host (e.g. "track 1" or "channel 4").
*
* If supplied by host, the string will be referenced only during
* LV2UI_Descriptor::instantiate()
*/
const char * plugin_human_id;
} LV2_External_UI_Host;
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* LV2_EXTERNAL_UI_H */
/*
* Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sandbox_slave.h>
#include <Elementary.h>
typedef struct _app_t app_t;
struct _app_t {
sandbox_slave_t *sb;
Evas_Object *win;
Evas_Object *bg;
Evas_Object *widget;
Ecore_Fd_Handler *fd;
};
static Eina_Bool
_recv(void *data, Ecore_Fd_Handler *fd_handler)
{
sandbox_slave_t *sb = data;
sandbox_slave_recv(sb);
return ECORE_CALLBACK_RENEW;
}
static void
_del_request(void *data, Evas_Object *obj, void *event_info)
{
app_t *app = data;
elm_exit();
app->bg = NULL;
app->win = NULL;
}
static inline int
_init(sandbox_slave_t *sb, void *data)
{
app_t *app= data;
int w = 640;
int h = 360;
const char *title = sandbox_slave_title_get(sb);
app->win = elm_win_add(NULL, title, ELM_WIN_BASIC);
if(!app->win)
{
fprintf(stderr, "elm_win_add failed\n");
goto fail;
}
elm_win_title_set(app->win, title);
elm_win_autodel_set(app->win, EINA_TRUE);
evas_object_smart_callback_add(app->win, "delete,request", _del_request, app);
app->bg = elm_bg_add(app->win);
if(!app->bg)
{
fprintf(stderr, "elm_bg_add failed\n");
goto fail;
}
elm_bg_color_set(app->bg, 64, 64, 64);
evas_object_size_hint_weight_set(app->bg, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(app->bg, EVAS_HINT_FILL, EVAS_HINT_FILL);
evas_object_show(app->bg);
elm_win_resize_object_add(app->win, app->bg);
if( sandbox_slave_instantiate(sb, (void *)app->win, (void *)&app->widget)
|| !app->widget)
{
fprintf(stderr, "sandbox_slave_instantiate failed\n");
goto fail;
}
evas_object_size_hint_weight_set(app->widget, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
evas_object_size_hint_align_set(app->widget, EVAS_HINT_FILL, EVAS_HINT_FILL);
// get widget size hint
int W, H;
evas_object_size_hint_min_get(app->widget, &W, &H);
if(W != 0)
w = W;
if(H != 0)
h = H;
evas_object_show(app->widget);
elm_win_resize_object_add(app->win, app->widget);
evas_object_resize(app->win, w, h);
evas_object_show(app->win);
int fd;
sandbox_slave_fd_get(sb, &fd);
if(fd == -1)
{
fprintf(stderr, "sandbox_slave_instantiate failed\n");
goto fail;
}
app->fd= ecore_main_fd_handler_add(fd, ECORE_FD_READ,
_recv, sb, NULL, NULL);
if(!app->fd)
{
fprintf(stderr, "ecore_main_fd_handler_add failed\n");
goto fail;
}
return 0;
fail:
return -1;
}
static inline void
_run(sandbox_slave_t *sb, void *data)
{
app_t *app = data;
elm_run();
}
static inline void
_deinit(void *data)
{
app_t *app = data;
if(app->fd)
ecore_main_fd_handler_del(app->fd);
if(app->bg)
{
elm_win_resize_object_del(app->win, app->bg);
evas_object_hide(app->bg);
evas_object_del(app->bg);
}
if(app->win)
{
evas_object_hide(app->win);
evas_object_del(app->win);
}
}
static const sandbox_slave_driver_t driver = {
.init_cb = _init,
.run_cb = _run,
.deinit_cb = _deinit,
.resize_cb = NULL
};
static int
elm_main(int argc, char **argv)
{
static app_t app;
#ifdef ELM_1_10
elm_config_accel_preference_set("gl");
#endif
app.sb = sandbox_slave_new(argc, argv, &driver, &app);
if(app.sb)
{
sandbox_slave_run(app.sb);
sandbox_slave_free(app.sb);
printf("bye from %s\n", argv[0]);
return 0;
}
printf("fail from %s\n", argv[0]);
return -1;
}
ELM_MAIN();
This diff is collapsed.
/*
* Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sandbox_master.h>
#include <sandbox_io.h>
#include <lv2/lv2plug.in/ns/ext/log/log.h>
#include <lv2/lv2plug.in/ns/ext/options/options.h>
#include <lv2/lv2plug.in/ns/extensions/ui/ui.h>
struct _sandbox_master_t {
sandbox_io_t io;
sandbox_master_driver_t *driver;
void *data;
};
sandbox_master_t *
sandbox_master_new(sandbox_master_driver_t *driver, void *data)
{
sandbox_master_t *sb = calloc(1, sizeof(sandbox_master_t));
if(!sb)
goto fail;
sb->driver = driver;
sb->data = data;
if(_sandbox_io_init(&sb->io, driver->map, driver->unmap, driver->socket_path, true))
goto fail;
return sb;
fail:
sandbox_master_free(sb);
return NULL;
}
void
sandbox_master_free(sandbox_master_t *sb)
{
if(sb)
{
_sandbox_io_deinit(&sb->io);
free(sb);
}
}
void
sandbox_master_recv(sandbox_master_t *sb)
{
if(sb)
_sandbox_io_recv(&sb->io, sb->driver->recv_cb, sb->driver->subscribe_cb, sb->data);
}
bool
sandbox_master_send(sandbox_master_t *sb, uint32_t index, uint32_t size,
uint32_t format, const void *buf)
{
if(sb)
return _sandbox_io_send(&sb->io, index, size, format, buf);
return false;
}
bool
sandbox_master_flush(sandbox_master_t *sb)
{
if(sb)
return _sandbox_io_flush(&sb->io);
return false;
}
void
sandbox_master_fd_get(sandbox_master_t *sb, int *fd)
{
if(sb && fd)
*fd = _sandbox_io_fd_get(&sb->io);
else if(fd)
*fd = -1;
}
/*
* Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#ifndef _SANDBOX_MASTER_H
#define _SANDBOX_MASTER_H
#include <lv2/lv2plug.in/ns/ext/urid/urid.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _sandbox_master_t sandbox_master_t;
typedef struct _sandbox_master_driver_t sandbox_master_driver_t;
typedef void (*sandbox_master_recv_cb_t)(void *data, uint32_t index, uint32_t size,
uint32_t format, const void *buf);
typedef void (*sandbox_master_subscribe_cb_t)(void *data, uint32_t index,
uint32_t protocol, bool state);
struct _sandbox_master_driver_t {
const char *socket_path;
LV2_URID_Map *map;
LV2_URID_Unmap *unmap;
sandbox_master_recv_cb_t recv_cb;
sandbox_master_subscribe_cb_t subscribe_cb;
};
sandbox_master_t *
sandbox_master_new(sandbox_master_driver_t *driver, void *data);
void
sandbox_master_free(sandbox_master_t *sb);
void
sandbox_master_recv(sandbox_master_t *sb);
bool
sandbox_master_send(sandbox_master_t *sb, uint32_t index, uint32_t size,
uint32_t format, const void *buf);
bool
sandbox_master_flush(sandbox_master_t *sb);
void
sandbox_master_fd_get(sandbox_master_t *sb, int *fd);
#ifdef __cplusplus
}
#endif
#endif
This diff is collapsed.
/*
* Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#ifndef _SANDBOX_SLAVE_H
#define _SANDBOX_SLAVE_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _sandbox_slave_t sandbox_slave_t;
typedef struct _sandbox_slave_driver_t sandbox_slave_driver_t;
typedef int (*sandbox_slave_driver_init_t)(sandbox_slave_t *sb, void *data);
typedef void (*sandbox_slave_driver_run_t)(sandbox_slave_t *sb, void *data);
typedef void (*sandbox_slave_driver_deinit_t)(void *data);
typedef int (*sandbox_slave_driver_resize_t)(void *data, int width, int height);
struct _sandbox_slave_driver_t {
sandbox_slave_driver_init_t init_cb;
sandbox_slave_driver_run_t run_cb;
sandbox_slave_driver_deinit_t deinit_cb;
sandbox_slave_driver_resize_t resize_cb;
};
sandbox_slave_t *
sandbox_slave_new(int argc, char **argv, const sandbox_slave_driver_t *driver, void *data);
void
sandbox_slave_free(sandbox_slave_t *sb);
int
sandbox_slave_instantiate(sandbox_slave_t *sb, void *parent, void *widget);
void
sandbox_slave_recv(sandbox_slave_t *sb);
bool
sandbox_slave_flush(sandbox_slave_t *sb);
int
sandbox_slave_idle(sandbox_slave_t *sb);
void
sandbox_slave_run(sandbox_slave_t *sb);
void
sandbox_slave_fd_get(sandbox_slave_t *sb, int *fd);
const char *
sandbox_slave_title_get(sandbox_slave_t *sb);
#ifdef __cplusplus
}
#endif
#endif
/*
* Copyright (c) 2015-2016 Hanspeter Portner (dev@open-music-kontrollers.ch)
*
* This is free software: you can redistribute it and/or modify
* it under the terms of the Artistic License 2.0 as published by
* The Perl Foundation.
*
* This source is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* Artistic License 2.0 for more details.
*
* You should have received a copy of the Artistic License 2.0
* along the source as a COPYING file. If not, obtain it from
* http://www.perlfoundation.org/artistic_license_2_0.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <sys/wait.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <lv2/lv2plug.in/ns/ext/options/options.h>
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
#include <sandbox_ui.h>
#include <sandbox_master.h>
#include <lv2_external_ui.h> // kxstudio external-ui extension
#define SOCKET_PATH_LEN 32
typedef struct _plughandle_t plughandle_t;
struct _plughandle_t {
int done;
LV2UI_Write_Function write_function;
LV2UI_Controller controller;
LV2UI_Port_Subscribe *subscribe;
sandbox_master_driver_t driver;
sandbox_master_t *sb;
char *plugin_uri;
char *bundle_path;
char *executable;
char *ui_uri;
char *window_title;
char socket_path [SOCKET_PATH_LEN];
LV2_URID ui_window_title;
LV2_URID atom_string;
pid_t pid;
struct {
LV2_External_UI_Widget widget;
const LV2_External_UI_Host *host;
} kx;
};
static void
_recv(LV2UI_Controller controller, uint32_t port,
uint32_t size, uint32_t protocol, const void *buf)
{
plughandle_t *handle = controller;
handle->write_function(handle->controller, port, size, protocol, buf);
}
static void
_subscribe(LV2UI_Controller controller, uint32_t port,
uint32_t protocol, bool state)
{
plughandle_t *handle = controller;
if(handle->subscribe)
{
if(state)
handle->subscribe->subscribe(handle->subscribe->handle,
port, protocol, NULL);
else
handle->subscribe->unsubscribe(handle->subscribe->handle,
port, protocol, NULL);
}
}
// Show Interface
static inline int
_show_cb(LV2UI_Handle instance)
{
plughandle_t *handle = instance;
if(!handle->done)
return 0; // already showing
strncpy(handle->socket_path, "ipc:///tmp/sandbox_ui_XXXXXX", SOCKET_PATH_LEN);
int fd = mkstemp(&handle->socket_path[6]);
if(!fd)
return -1;
close(fd);
handle->sb = sandbox_master_new(&handle->driver, handle);
if(!handle->sb)
return -1;
handle->pid = fork();
if(handle->pid == 0) // child
{
char *const argv [] = {
handle->executable,
"-p", handle->plugin_uri,
"-b", handle->bundle_path,
"-u", handle->ui_uri,
"-s", handle->socket_path,
"-w", handle->window_title,
NULL
};
execv(handle->executable, argv); // p = search PATH for executable
printf("fork child failed\n");
exit(-1);
}
else if(handle->pid < 0)
{
printf("fork failed\n");
return -1;
}
handle->done = 0;
return 0;
}
static inline int
_hide_cb(LV2UI_Handle instance)
{
plughandle_t *handle = instance;
if(handle->pid > 0) // has child
{
kill(handle->pid, SIGINT);
int status;
waitpid(handle->pid, &status, 0);
handle->pid = -1; // invalidate
}
if(handle->sb)
{
sandbox_master_free(handle->sb);
handle->sb = NULL;
}
/* FIXME
remove(&handle->socket_path[6]);
*/
if(handle->kx.host && handle->kx.host->ui_closed)
handle->kx.host->ui_closed(handle->controller);
handle->done = 1;
return 0;
}
static const LV2UI_Show_Interface show_ext = {
.show = _show_cb,
.hide = _hide_cb
};
// Idle interface
static inline int
_idle_cb(LV2UI_Handle instance)
{
plughandle_t *handle = instance;
if(handle->pid > 0)
{
int status;
int res;
if((res = waitpid(handle->pid, &status, WNOHANG)) < 0)
{
if(errno == ECHILD)
{
handle->pid = -1; // invalidate
//_hide_cb(ui);
handle->done = 1;
}
}
else if( (res > 0) && WIFEXITED(status) )
{
handle->pid = -1; // invalidate
//_hide_cb(ui);