ZynAddSubFX-UI-Zest.cpp (8083B)
1 /* 2 ZynAddSubFX - a software synthesizer 3 4 ZynAddSubFX-UI.cpp - DPF + ZynAddSubFX External UI 5 Copyright (C) 2015-2016 Filipe Coelho 6 Author: Filipe Coelho 7 8 This program is free software; you can redistribute it and/or 9 modify it under the terms of the GNU General Public License 10 as published by the Free Software Foundation; either version 2 11 of the License, or (at your option) any later version. 12 */ 13 14 #if !defined(WIN32) && !defined(__APPLE__) 15 #include <string> 16 #include <unistd.h> 17 #include "zyn-config.h" 18 #endif 19 20 // DPF includes 21 #include "DistrhoUI.hpp" 22 #ifdef WIN32 23 #include <windows.h> 24 #else 25 #ifndef __USE_GNU 26 #define __USE_GNU 27 #endif 28 #include <dlfcn.h> 29 #endif 30 31 typedef void *zest_t; 32 struct zest_handles { 33 zest_t *(*zest_open)(const char *); 34 void (*zest_close)(zest_t*); 35 void (*zest_setup)(zest_t*); 36 void (*zest_draw)(zest_t*); 37 void (*zest_motion)(zest_t*, int x, int y, int mod); 38 void (*zest_scroll)(zest_t*, int x, int y, int dx, int dy, int mod); 39 void (*zest_mouse)(zest_t *z, int button, int action, int x, int y, int mod); 40 void (*zest_key)(zest_t *z, char *key, bool press); 41 void (*zest_resize)(zest_t *z, int w, int h); 42 void (*zest_special)(zest_t *z, int key, int press); 43 int (*zest_tick)(zest_t*); 44 void (*zest_forget_all_state) (zest_t*); 45 zest_t *zest; 46 }; 47 48 /* ------------------------------------------------------------------------------------------------------------ 49 * ZynAddSubFX UI class */ 50 51 class ZynAddSubFXUI : public UI 52 { 53 public: 54 ZynAddSubFXUI() 55 : UI(1181, 659) 56 { 57 printf("[INFO] Opened the zynaddsubfx UI...\n"); 58 #ifdef WIN32 59 char path[1024]; 60 GetModuleFileName(GetModuleHandle("ZynAddSubFX.dll"), path, sizeof(path)); 61 if(strstr(path, "ZynAddSubFX.dll")) 62 strstr(path, "ZynAddSubFX.dll")[0] = 0; 63 strcat(path, "libzest.dll"); 64 printf("[DEBUG] Loading zest library from <%s>\n", path); 65 handle = LoadLibrary(path); 66 if(!handle) 67 handle = LoadLibrary("./libzest.dll"); 68 if(!handle) 69 handle = LoadLibrary("libzest.dll"); 70 #elif defined __APPLE__ 71 handle = dlopen("@loader_path/libzest.dylib", RTLD_NOW | RTLD_LOCAL); 72 if(!handle) // VST 73 handle = dlopen("@loader_path/../Resources/libzest.dylib", RTLD_LAZY); 74 #else 75 if(zyn::fusion_dir && *zyn::fusion_dir) 76 { 77 std::string fusion = zyn::fusion_dir; 78 fusion += "/libzest.so"; 79 if(access(fusion.c_str(), R_OK)) 80 fputs("Warning: CMake's ZynFusionDir does not contain a" 81 "\"libzest.so\" library - ignoring.", stderr); 82 else 83 handle = dlopen(fusion.c_str(), RTLD_LAZY); 84 } 85 if(!handle) 86 handle = dlopen("./libzest.so", RTLD_LAZY); 87 if(!handle) 88 handle = dlopen("/opt/zyn-fusion/libzest.so", RTLD_LAZY); 89 if(!handle) 90 handle = dlopen("libzest.so", RTLD_LAZY); 91 #endif 92 if(!handle) { 93 printf("[ERROR] Cannot Open libzest.so\n"); 94 #ifndef WIN32 95 printf("[ERROR] '%s'\n", dlerror()); 96 #endif 97 } 98 memset(&z, 0, sizeof(z)); 99 #ifdef WIN32 100 #define get_sym(x) z.zest_##x = (decltype(z.zest_##x))GetProcAddress(handle, "zest_"#x) 101 #else 102 #define get_sym(x) z.zest_##x = (decltype(z.zest_##x))dlsym(handle, "zest_"#x) 103 #endif 104 if(handle) { 105 get_sym(open); 106 get_sym(setup); 107 get_sym(close); 108 get_sym(draw); 109 get_sym(tick); 110 get_sym(key); 111 get_sym(motion); 112 get_sym(scroll); 113 get_sym(mouse); 114 get_sym(special); 115 get_sym(resize); 116 get_sym(forget_all_state); 117 } 118 oscPort = -1; 119 printf("[INFO] Ready to run\n"); 120 } 121 122 ~ZynAddSubFXUI() override 123 { 124 printf("[INFO:Zyn] zest_close()\n"); 125 if(z.zest) 126 z.zest_close(z.zest); 127 #ifdef WIN32 128 #else 129 if(handle) 130 dlclose(handle); 131 #endif 132 } 133 134 protected: 135 /* -------------------------------------------------------------------------------------------------------- 136 * DSP/Plugin Callbacks */ 137 138 /** 139 A parameter has changed on the plugin side. 140 This is called by the host to inform the UI about parameter changes. 141 */ 142 void parameterChanged(uint32_t index, float value) override 143 { 144 switch (index) 145 { 146 case kParamOscPort: { 147 const int port = int(value+0.5f); 148 149 if (oscPort != port) 150 { 151 oscPort = port; 152 repaint(); 153 } 154 } break; 155 } 156 } 157 158 /** 159 A program has been loaded on the plugin side. 160 This is called by the host to inform the UI about program changes. 161 */ 162 void programLoaded(uint32_t index) override 163 { 164 // Tell Zest that we need to reload the UI. 165 // Currently Zyn-Fusion doesn't use built-in program, 166 // and this event may not be raised. 167 if(z.zest) 168 z.zest_forget_all_state(z.zest); 169 } 170 171 /** 172 A state has changed on the plugin side. 173 This is called by the host to inform the UI about state changes. 174 */ 175 void stateChanged(const char* key, const char* value) override 176 { 177 // Tell Zest that we need to reload the UI. 178 // This event will be raised when you load a preset from your host, 179 // or during UI loads. 180 if(z.zest) 181 z.zest_forget_all_state(z.zest); 182 } 183 184 /* -------------------------------------------------------------------------------------------------------- 185 * UI Callbacks */ 186 187 bool onScroll(const ScrollEvent &ev) override 188 { 189 if(z.zest) 190 z.zest_scroll(z.zest, ev.pos.getX(), ev.pos.getY(), ev.delta.getX(), ev.delta.getY(), ev.mod); 191 return false; 192 } 193 194 bool onSpecial(const SpecialEvent &ev) override 195 { 196 printf("special event = %d, %d\n", ev.key, ev.press); 197 if(z.zest) 198 z.zest_special(z.zest, ev.key, ev.press); 199 return false; 200 } 201 202 bool onMouse(const MouseEvent &m) override 203 { 204 if(z.zest) 205 z.zest_mouse(z.zest, m.button, m.press, m.pos.getX(), m.pos.getY(), m.mod); 206 return false; 207 } 208 209 bool onMotion(const MotionEvent &m) override 210 { 211 if(z.zest) 212 z.zest_motion(z.zest, m.pos.getX(), m.pos.getY(), m.mod); 213 return false; 214 } 215 216 /** 217 A function called to draw the view contents with OpenGL. 218 */ 219 void onDisplay() override 220 { 221 if(oscPort < 1) 222 return; 223 if(!z.zest) { 224 if(!z.zest_open) 225 return; 226 if(!oscPort) 227 return; 228 printf("[INFO:Zyn] zest_open()\n"); 229 char address[1024]; 230 snprintf(address, sizeof(address), "osc.udp://127.0.0.1:%d",oscPort); 231 printf("[INFO:Zyn] zest_open(%s)\n", address); 232 233 z.zest = z.zest_open(address); 234 printf("[INFO:Zyn] zest_setup(%s)\n", address); 235 z.zest_setup(z.zest); 236 } 237 238 z.zest_draw(z.zest); 239 } 240 241 bool onKeyboard(const KeyboardEvent &ev) 242 { 243 char c[2] = {}; 244 if(ev.key < 128) 245 c[0] = ev.key; 246 if(z.zest && c[0]) 247 z.zest_key(z.zest, c, ev.press); 248 return true; 249 } 250 251 void uiIdle(void) override 252 { 253 if(z.zest) { 254 if (z.zest_tick(z.zest)) { 255 repaint(); 256 } 257 } 258 } 259 260 void uiReshape(uint width, uint height) 261 { 262 if(z.zest) 263 z.zest_resize(z.zest, width, height); 264 } 265 266 private: 267 int oscPort; 268 zest_handles z; 269 #ifdef WIN32 270 HMODULE handle = nullptr; 271 #else 272 void *handle = nullptr; 273 #endif 274 275 276 DISTRHO_DECLARE_NON_COPY_CLASS(ZynAddSubFXUI) 277 }; 278 279 /* ------------------------------------------------------------------------------------------------------------ 280 * Create UI, entry point */ 281 282 START_NAMESPACE_DISTRHO 283 284 UI* createUI() 285 { 286 return new ZynAddSubFXUI(); 287 } 288 289 END_NAMESPACE_DISTRHO