/* * Tibia * * Copyright (C) 2024 Orastron Srl unipersonale * * Tibia is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, version 3 of the License. * * Tibia 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 * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Tibia. If not, see <http://www.gnu.org/licenses/>. * * File author: Stefano D'Angelo, Paolo Marrone */ #if defined(_WIN32) || defined(__CYGWIN__) #elif defined(__APPLE__) #else # include <X11/Xlib.h> #endif typedef struct { void * widget; #if defined(_WIN32) || defined(__CYGWIN__) #elif defined(__APPLE__) #else Display * display; #endif float gain; float delay; float cutoff; char bypass; float y_z1; unsigned int width; unsigned int height; plugin_ui_callbacks cbs; } plugin_ui; #define WIDTH 600.0 #define HEIGHT 400.0 static void plugin_ui_get_default_size(uint32_t *width, uint32_t *height) { *width = WIDTH; *height = HEIGHT; } static plugin_ui *plugin_ui_create(char has_parent, void *parent, plugin_ui_callbacks *cbs) { plugin_ui *instance = malloc(sizeof(plugin_ui)); if (instance == NULL) return NULL; #if defined(_WIN32) || defined(__CYGWIN__) #elif defined(__APPLE__) #else instance->display = XOpenDisplay(NULL); if (instance->display == NULL) { free(instance); return NULL; } int s = DefaultScreen(instance->display); Window w = XCreateSimpleWindow(instance->display, has_parent ? (Window)parent : RootWindow(instance->display, s), 0, 0, WIDTH, HEIGHT, 0, 0, 0); XSelectInput(instance->display, w, ExposureMask | StructureNotifyMask); XMapWindow(instance->display, w); XSync(instance->display, False); instance->widget = (void *)w; instance->width = WIDTH; instance->height = HEIGHT; #endif instance->cbs = *cbs; return instance; } static void plugin_ui_free(plugin_ui *instance) { XDestroyWindow(instance->display, (Window)instance->widget); XCloseDisplay(instance->display); free(instance); } static void plugin_ui_idle(plugin_ui *instance) { #if defined(_WIN32) || defined(__CYGWIN__) #elif defined(__APPLE__) #else Window w = (Window)instance->widget; while (XEventsQueued(instance->display, QueuedAfterFlush) > 0) { XEvent e; XNextEvent(instance->display, &e); if (e.type == Expose) { XClearWindow(instance->display, w); GC gc = DefaultGC(instance->display, DefaultScreen(instance->display)); XSetForeground(instance->display, gc, 0xff0000); XFillRectangle(instance->display, w, gc, 10, 10, instance->width - 20, instance->height - 20); } else if (e.type == ConfigureNotify) { XWindowAttributes attrs; XGetWindowAttributes(instance->display, w, &attrs); instance->width = attrs.width; instance->height = attrs.height; } } #endif } static void plugin_ui_set_parameter(plugin_ui *instance, size_t index, float value) { switch (index) { case 0: instance->gain = 0.0125f * value + 0.75f; break; case 1: instance->delay = 0.001f * value; break; case 2: // (bad) approx log unmap instance->cutoff = (1.0326554320337176f * value - 20.65310864067435f) / (value + 632.4555320336754f); break; case 3: instance->bypass = value >= 0.5f; break; case 4: instance->y_z1 = 0.5f * value + 0.5f; break; } }