diff --git a/Makefile.base.mk b/Makefile.base.mk index 5e10d7da..ea729767 100644 --- a/Makefile.base.mk +++ b/Makefile.base.mk @@ -189,6 +189,8 @@ endif ifeq ($(HAVE_DGL),true) +DGL_FLAGS += -DHAVE_DGL + ifeq ($(MACOS),true) DGL_LIBS = -framework OpenGL -framework Cocoa endif @@ -198,8 +200,8 @@ DGL_LIBS = -lopengl32 -lgdi32 endif ifneq ($(MACOS_OR_WIN32),true) -DGL_FLAGS = $(shell pkg-config --cflags gl x11) -DGL_LIBS = $(shell pkg-config --libs gl x11) +DGL_FLAGS += $(shell pkg-config --cflags gl x11) +DGL_LIBS += $(shell pkg-config --libs gl x11) endif endif # HAVE_DGL diff --git a/dgl/Base.hpp b/dgl/Base.hpp index 30d10e0d..7b7864fe 100644 --- a/dgl/Base.hpp +++ b/dgl/Base.hpp @@ -73,6 +73,8 @@ // ----------------------------------------------------------------------- // OpenGL includes +#if defined(HAVE_DGL) + #ifdef DISTRHO_OS_MAC # include #else @@ -83,9 +85,20 @@ # include #endif +#endif + +// ----------------------------------------------------------------------- +// Cairo includes + +#if defined(HAVE_DCAIRO) +# include +#endif + // ----------------------------------------------------------------------- // Missing OpenGL defines +#if defined(HAVE_DGL) + #if defined(GL_BGR_EXT) && ! defined(GL_BGR) # define GL_BGR GL_BGR_EXT #endif @@ -98,6 +111,8 @@ # define GL_CLAMP_TO_BORDER 0x812D #endif +#endif + #ifdef DISTRHO_OS_WINDOWS // ----------------------------------------------------------------------- // Fix OpenGL includes for Windows, based on glfw code diff --git a/dgl/Color.hpp b/dgl/Color.hpp index 2fc8c64c..51d8afc8 100644 --- a/dgl/Color.hpp +++ b/dgl/Color.hpp @@ -19,7 +19,9 @@ #include "Base.hpp" +#if !defined(HAVE_DCAIRO) struct NVGcolor; +#endif START_NAMESPACE_DGL @@ -95,12 +97,14 @@ struct Color { */ void fixBounds() noexcept; +#if !defined(HAVE_DCAIRO) /** @internal Needed for NanoVG compatibility. */ Color(const NVGcolor&) noexcept; operator NVGcolor() const noexcept; +#endif }; // ----------------------------------------------------------------------- diff --git a/dgl/Geometry.hpp b/dgl/Geometry.hpp index 3dbf7064..b82230f1 100644 --- a/dgl/Geometry.hpp +++ b/dgl/Geometry.hpp @@ -346,10 +346,12 @@ public: */ void moveBy(const Point& pos) noexcept; +#if defined(HAVE_DGL) /** Draw this line using the current OpenGL state. */ void draw(); +#endif /** Return true if line is null (start and end pos are equal). @@ -460,6 +462,7 @@ public: */ void setNumSegments(const uint num); +#if defined(HAVE_DGL) /** Draw this circle using the current OpenGL state. */ @@ -469,6 +472,7 @@ public: Draw lines (outline of this circle) using the current OpenGL state. */ void drawOutline(); +#endif Circle& operator=(const Circle& cir) noexcept; bool operator==(const Circle& cir) const noexcept; @@ -482,7 +486,9 @@ private: // cached values float fTheta, fCos, fSin; +#if defined(HAVE_DGL) void _draw(const bool outline); +#endif }; // ----------------------------------------------------------------------- @@ -516,6 +522,7 @@ public: */ Triangle(const Triangle& tri) noexcept; +#if defined(HAVE_DGL) /** Draw this triangle using the current OpenGL state. */ @@ -525,6 +532,7 @@ public: Draw lines (outline of this triangle) using the current OpenGL state. */ void drawOutline(); +#endif /** Return true if triangle is null (all its points are equal). @@ -556,7 +564,9 @@ public: private: Point fPos1, fPos2, fPos3; +#if defined(HAVE_DGL) void _draw(const bool outline); +#endif }; // ----------------------------------------------------------------------- @@ -720,6 +730,7 @@ public: */ bool containsY(const T& y) const noexcept; +#if defined(HAVE_DGL) /** Draw this rectangle using the current OpenGL state. */ @@ -729,6 +740,7 @@ public: Draw lines (outline of this rectangle) using the current OpenGL state. */ void drawOutline(); +#endif Rectangle& operator=(const Rectangle& rect) noexcept; Rectangle& operator*=(double m) noexcept; @@ -740,7 +752,9 @@ private: Point fPos; Size fSize; +#if defined(HAVE_DGL) void _draw(const bool outline); +#endif }; // ----------------------------------------------------------------------- diff --git a/dgl/Widget.hpp b/dgl/Widget.hpp index 73d2d6e9..bebe5ed7 100644 --- a/dgl/Widget.hpp +++ b/dgl/Widget.hpp @@ -312,6 +312,10 @@ public: */ Window& getParentWindow() const noexcept; +#if defined(HAVE_DCAIRO) + cairo_t* getGraphics() const noexcept; +#endif + /** Check if this widget contains the point defined by @a x and @a y. */ diff --git a/dgl/Window.hpp b/dgl/Window.hpp index dbe3abfd..2a9d9517 100644 --- a/dgl/Window.hpp +++ b/dgl/Window.hpp @@ -119,6 +119,10 @@ public: Application& getApp() const noexcept; intptr_t getWindowId() const noexcept; +#if defined(HAVE_DCAIRO) + cairo_t* getGraphics() const noexcept; +#endif + void addIdleCallback(IdleCallback* const callback); void removeIdleCallback(IdleCallback* const callback); diff --git a/dgl/src/Color.cpp b/dgl/src/Color.cpp index 2ea9819f..4965c902 100644 --- a/dgl/src/Color.cpp +++ b/dgl/src/Color.cpp @@ -16,7 +16,9 @@ #include "../Color.hpp" +#if !defined(HAVE_DCAIRO) #include "nanovg/nanovg.h" +#endif START_NAMESPACE_DGL @@ -105,7 +107,36 @@ Color::Color(const Color& color1, const Color& color2, float u) noexcept Color Color::fromHSL(float hue, float saturation, float lightness, float alpha) { +#if defined(HAVE_DGL) return nvgHSLA(hue, saturation, lightness, static_cast(getFixedRange(alpha)*255.0f)); +#else + float m1, m2; + Color col; + hue = fmodf(hue, 1.0f); + if (hue < 0.0f) hue += 1.0f; + fixRange(saturation); + fixRange(lightness); + m2 = lightness <= 0.5f ? (lightness * (1 + saturation)) : (lightness + saturation - lightness * saturation); + m1 = 2 * lightness - m2; + auto hue_ = [](float h, float m1, float m2) -> float + { + if (h < 0) h += 1; + if (h > 1) h -= 1; + if (h < 1.0f/6.0f) + return m1 + (m2 - m1) * h * 6.0f; + else if (h < 3.0f/6.0f) + return m2; + else if (h < 4.0f/6.0f) + return m1 + (m2 - m1) * (2.0f/3.0f - h) * 6.0f; + return m1; + }; + col.red = hue_(hue + 1.0f/3.0f, m1, m2); + col.green = hue_(hue, m1, m2); + col.blue = hue_(hue - 1.0f/3.0f, m1, m2); + col.alpha = alpha; + col.fixBounds(); + return col; +#endif } Color Color::fromHTML(const char* rgb, float alpha) @@ -224,6 +255,7 @@ void Color::fixBounds() noexcept // ----------------------------------------------------------------------- +#if !defined(HAVE_DCAIRO) Color::Color(const NVGcolor& c) noexcept : red(c.r), green(c.g), blue(c.b), alpha(c.a) { @@ -239,6 +271,7 @@ Color::operator NVGcolor() const noexcept nc.a = alpha; return nc; } +#endif // ----------------------------------------------------------------------- diff --git a/dgl/src/Geometry.cpp b/dgl/src/Geometry.cpp index 7ea3af34..78eebdf1 100644 --- a/dgl/src/Geometry.cpp +++ b/dgl/src/Geometry.cpp @@ -441,6 +441,7 @@ void Line::moveBy(const Point& pos) noexcept fPosEnd.moveBy(pos); } +#if defined(HAVE_DGL) template void Line::draw() { @@ -455,6 +456,7 @@ void Line::draw() glEnd(); } +#endif template bool Line::isNull() const noexcept @@ -614,6 +616,7 @@ void Circle::setNumSegments(const uint num) fSin = std::sin(fTheta); } +#if defined(HAVE_DGL) template void Circle::draw() { @@ -625,6 +628,7 @@ void Circle::drawOutline() { _draw(true); } +#endif template Circle& Circle::operator=(const Circle& cir) noexcept @@ -650,6 +654,7 @@ bool Circle::operator!=(const Circle& cir) const noexcept return (fPos != cir.fPos || d_isNotEqual(fSize, cir.fSize) || fNumSegments != cir.fNumSegments); } +#if defined(HAVE_DGL) template void Circle::_draw(const bool outline) { @@ -670,6 +675,7 @@ void Circle::_draw(const bool outline) glEnd(); } +#endif // ----------------------------------------------------------------------- // Triangle @@ -698,6 +704,7 @@ Triangle::Triangle(const Triangle& tri) noexcept fPos2(tri.fPos2), fPos3(tri.fPos3) {} +#if defined(HAVE_DGL) template void Triangle::draw() { @@ -709,6 +716,7 @@ void Triangle::drawOutline() { _draw(true); } +#endif template bool Triangle::isNull() const noexcept @@ -755,6 +763,7 @@ bool Triangle::operator!=(const Triangle& tri) const noexcept return (fPos1 != tri.fPos1 || fPos2 != tri.fPos2 || fPos3 != tri.fPos3); } +#if defined(HAVE_DGL) template void Triangle::_draw(const bool outline) { @@ -770,6 +779,7 @@ void Triangle::_draw(const bool outline) glEnd(); } +#endif // ----------------------------------------------------------------------- // Rectangle @@ -952,6 +962,7 @@ bool Rectangle::containsY(const T& y) const noexcept return (y >= fPos.fY && y <= fPos.fY + fSize.fHeight); } +#if defined(HAVE_DGL) template void Rectangle::draw() { @@ -963,6 +974,7 @@ void Rectangle::drawOutline() { _draw(true); } +#endif template Rectangle& Rectangle::operator=(const Rectangle& rect) noexcept @@ -998,6 +1010,7 @@ bool Rectangle::operator!=(const Rectangle& rect) const noexcept return (fPos != rect.fPos || fSize != rect.fSize); } +#if defined(HAVE_DGL) template void Rectangle::_draw(const bool outline) { @@ -1021,6 +1034,7 @@ void Rectangle::_draw(const bool outline) glEnd(); } +#endif // ----------------------------------------------------------------------- // Possible template data types diff --git a/dgl/src/Widget.cpp b/dgl/src/Widget.cpp index d200fb40..bf6fd3f8 100644 --- a/dgl/src/Widget.cpp +++ b/dgl/src/Widget.cpp @@ -189,6 +189,13 @@ Window& Widget::getParentWindow() const noexcept return pData->parent; } +#if defined(HAVE_DCAIRO) +cairo_t* Widget::getGraphics() const noexcept +{ + return pData->parent.getGraphics(); +} +#endif + bool Widget::contains(int x, int y) const noexcept { return (x >= 0 && y >= 0 && static_cast(x) < pData->size.getWidth() && static_cast(y) < pData->size.getHeight()); diff --git a/dgl/src/WidgetPrivateData.hpp b/dgl/src/WidgetPrivateData.hpp index 5dbe2ace..53f68f45 100644 --- a/dgl/src/WidgetPrivateData.hpp +++ b/dgl/src/WidgetPrivateData.hpp @@ -68,6 +68,7 @@ struct Widget::PrivateData { if ((skipDisplay && ! renderingSubWidget) || size.isInvalid() || ! visible) return; +#if defined(HAVE_DGL) bool needsDisableScissor = false; // reset color @@ -106,15 +107,18 @@ struct Widget::PrivateData { glEnable(GL_SCISSOR_TEST); needsDisableScissor = true; } +#endif // display widget self->onDisplay(); +#if defined(HAVE_DGL) if (needsDisableScissor) { glDisable(GL_SCISSOR_TEST); needsDisableScissor = false; } +#endif displaySubWidgets(width, height, scaling); } diff --git a/dgl/src/Window.cpp b/dgl/src/Window.cpp index ae46addb..18ea39f4 100644 --- a/dgl/src/Window.cpp +++ b/dgl/src/Window.cpp @@ -19,6 +19,16 @@ #include "../Base.hpp" +#undef PUGL_HAVE_CAIRO +#undef PUGL_HAVE_GL + +#if defined(HAVE_DGL) +#define PUGL_HAVE_GL 1 +#endif +#if defined(HAVE_DCAIRO) +#define PUGL_HAVE_CAIRO 1 +#endif + #include "pugl/pugl.h" #if defined(__GNUC__) && (__GNUC__ >= 7) @@ -203,6 +213,14 @@ struct Window::PrivateData { return; } +#if defined(HAVE_DGL) + PuglContextType contextType = PUGL_GL; +#endif +#if defined(HAVE_DCAIRO) + PuglContextType contextType = PUGL_CAIRO; +#endif + + puglInitContextType(fView, contextType); puglInitUserResizable(fView, fResizable); puglInitWindowSize(fView, static_cast(fWidth), static_cast(fHeight)); @@ -222,11 +240,12 @@ struct Window::PrivateData { puglCreateWindow(fView, nullptr); PuglInternals* impl = fView->impl; + #if defined(DISTRHO_OS_WINDOWS) hwnd = impl->hwnd; DISTRHO_SAFE_ASSERT(hwnd != 0); #elif defined(DISTRHO_OS_MAC) - mView = impl->glview; + mView = impl->view; mWindow = impl->window; DISTRHO_SAFE_ASSERT(mView != nullptr); if (fUsingEmbed) { @@ -1081,7 +1100,7 @@ struct Window::PrivateData { HWND hwndParent; #elif defined(DISTRHO_OS_MAC) bool fNeedsIdle; - PuglOpenGLView* mView; + NSView* mView; id mWindow; id mParentWindow; #else @@ -1365,6 +1384,13 @@ intptr_t Window::getWindowId() const noexcept return puglGetNativeWindow(pData->fView); } +#if defined(HAVE_DCAIRO) +cairo_t* Window::getGraphics() const noexcept +{ + return (cairo_t*)puglGetContext(pData->fView); +} +#endif + void Window::_addWidget(Widget* const widget) { pData->addWidget(widget); @@ -1400,8 +1426,10 @@ void Window::removeIdleCallback(IdleCallback* const callback) void Window::onDisplayBefore() { +#if defined(HAVE_DGL) glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); +#endif } void Window::onDisplayAfter() @@ -1410,6 +1438,7 @@ void Window::onDisplayAfter() void Window::onReshape(uint width, uint height) { +#if defined(HAVE_DGL) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_PROJECTION); @@ -1418,6 +1447,7 @@ void Window::onReshape(uint width, uint height) glViewport(0, 0, static_cast(width), static_cast(height)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); +#endif } void Window::onClose() diff --git a/dgl/src/pugl/pugl.h b/dgl/src/pugl/pugl.h index 32a10a2b..a2ffa85d 100644 --- a/dgl/src/pugl/pugl.h +++ b/dgl/src/pugl/pugl.h @@ -273,6 +273,20 @@ puglInitUserResizable(PuglView* view, bool resizable); PUGL_API void puglInitTransientFor(PuglView* view, uintptr_t parent); +/** + Drawing context type. +*/ +typedef enum { + PUGL_GL, + PUGL_CAIRO +} PuglContextType; + +/** + Set the context type before creating a window. +*/ +PUGL_API void +puglInitContextType(PuglView* view, PuglContextType type); + /** @} */ @@ -349,6 +363,14 @@ puglSetHandle(PuglView* view, PuglHandle handle); PUGL_API PuglHandle puglGetHandle(PuglView* view); +/** + Get the drawing context. + For PUGL_GL contexts, this is unused and returns NULL. + For PUGL_CAIRO contexts, this returns a pointer to a cairo_t. +*/ +PUGL_API void* +puglGetContext(PuglView* view); + /** Return the timestamp (if any) of the currently-processing event. */ diff --git a/dgl/src/pugl/pugl_internal.h b/dgl/src/pugl/pugl_internal.h index fa52df40..b8d9ca93 100644 --- a/dgl/src/pugl/pugl_internal.h +++ b/dgl/src/pugl/pugl_internal.h @@ -41,6 +41,7 @@ struct PuglViewImpl { PuglInternals* impl; PuglNativeWindow parent; + PuglContextType ctx_type; uintptr_t transient_parent; int width; @@ -140,6 +141,12 @@ puglCreate(PuglNativeWindow parent, return view; } +void +puglInitContextType(PuglView* view, PuglContextType type) +{ + view->ctx_type = type; +} + void puglSetHandle(PuglView* view, PuglHandle handle) { @@ -239,6 +246,7 @@ puglLeaveContext(PuglView* view, bool flush); static void puglDefaultReshape(int width, int height) { +#ifdef PUGL_HAVE_GL #ifdef ROBTK_HERE glViewport(0, 0, width, height); glMatrixMode(GL_PROJECTION); @@ -257,4 +265,5 @@ puglDefaultReshape(int width, int height) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); #endif +#endif } diff --git a/dgl/src/pugl/pugl_osx.m b/dgl/src/pugl/pugl_osx.m index 738103f3..1c00106d 100644 --- a/dgl/src/pugl/pugl_osx.m +++ b/dgl/src/pugl/pugl_osx.m @@ -21,6 +21,10 @@ #include #import +#ifdef PUGL_HAVE_CAIRO +#import +#import +#endif #include "pugl_internal.h" @@ -93,7 +97,40 @@ puglDisplay(PuglView* view) } } -@interface PuglOpenGLView : NSOpenGLView +@protocol PuglGenericView +@required +- (PuglView *) puglView; +- (void) setPuglview:(PuglView *)pv; +@end + +static unsigned +getModifiers(PuglView* view, NSEvent* ev) +{ + const unsigned modifierFlags = [ev modifierFlags]; + + view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX); + + unsigned mods = 0; + mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0; + mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0; + mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0; + mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0; + return mods; +} + +static int +getFixedAppKitButton(NSInteger button) +{ + switch (button) { + case 0: return 1; + case 1: return 3; + case 2: return 2; + default: return button; + } +} + +#ifdef PUGL_HAVE_GL +@interface PuglOpenGLView : NSOpenGLView { @public PuglView* puglview; @@ -101,6 +138,9 @@ puglDisplay(PuglView* view) bool doubleBuffered; } +- (PuglView *) puglView; +- (void) setPuglview:(PuglView *)pv; + - (BOOL) acceptsFirstMouse:(NSEvent*)e; - (BOOL) acceptsFirstResponder; - (BOOL) isFlipped; @@ -130,6 +170,13 @@ puglDisplay(PuglView* view) @end @implementation PuglOpenGLView +- (PuglView *) puglView { + return self->puglview; +} + +- (void) setPuglview:(PuglView *)pv { + self->puglview = pv; +} - (BOOL) acceptsFirstMouse:(NSEvent*)e { @@ -277,32 +324,296 @@ puglDisplay(PuglView* view) [super viewWillMoveToWindow:newWindow]; } -static unsigned -getModifiers(PuglView* view, NSEvent* ev) +- (void) mouseMoved:(NSEvent*)event { - const unsigned modifierFlags = [ev modifierFlags]; + if (puglview->motionFunc) { + NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; + puglview->mods = getModifiers(puglview, event); + puglview->motionFunc(puglview, loc.x, loc.y); + } +} - view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX); +- (void) mouseDragged:(NSEvent*)event +{ + [self mouseMoved:event]; +} - unsigned mods = 0; - mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0; - mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0; - mods |= (modifierFlags & NSAlternateKeyMask) ? PUGL_MOD_ALT : 0; - mods |= (modifierFlags & NSCommandKeyMask) ? PUGL_MOD_SUPER : 0; - return mods; +- (void) rightMouseDragged:(NSEvent*)event +{ + [self mouseDragged:event]; } -static int -getFixedAppKitButton(NSInteger button) +- (void) otherMouseDragged:(NSEvent*)event { - switch (button) { - case 0: return 1; - case 1: return 3; - case 2: return 2; - default: return button; + [self mouseDragged:event]; +} + +- (void) mouseDown:(NSEvent*)event +{ + if (puglview->mouseFunc) { + NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; + puglview->mods = getModifiers(puglview, event); + puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), true, loc.x, loc.y); + } +} + +- (void) rightMouseDown:(NSEvent*)event +{ + [self mouseDown:event]; +} + +- (void) otherMouseDown:(NSEvent*)event +{ + [self mouseDown:event]; +} + +- (void) mouseUp:(NSEvent*)event +{ + if (puglview->mouseFunc) { + NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; + puglview->mods = getModifiers(puglview, event); + puglview->mouseFunc(puglview, getFixedAppKitButton([event buttonNumber]), false, loc.x, loc.y); } } +- (void) rightMouseUp:(NSEvent*)event +{ + [self mouseUp:event]; +} + +- (void) otherMouseUp:(NSEvent*)event +{ + [self mouseUp:event]; +} + +- (void) scrollWheel:(NSEvent*)event +{ + if (puglview->scrollFunc) { + NSPoint loc = [self convertPoint:[event locationInWindow] fromView:nil]; + puglview->mods = getModifiers(puglview, event); + puglview->scrollFunc(puglview, + loc.x, loc.y, + [event deltaX], [event deltaY]); + } +} + +- (void) keyDown:(NSEvent*)event +{ + if (puglview->keyboardFunc && !(puglview->ignoreKeyRepeat && [event isARepeat])) { + NSString* chars = [event characters]; + puglview->mods = getModifiers(puglview, event); + puglview->keyboardFunc(puglview, true, [chars characterAtIndex:0]); + } +} + +- (void) keyUp:(NSEvent*)event +{ + if (puglview->keyboardFunc) { + NSString* chars = [event characters]; + puglview->mods = getModifiers(puglview, event); + puglview->keyboardFunc(puglview, false, [chars characterAtIndex:0]); + } +} + +- (void) flagsChanged:(NSEvent*)event +{ + if (puglview->specialFunc) { + const unsigned mods = getModifiers(puglview, event); + if ((mods & PUGL_MOD_SHIFT) != (puglview->mods & PUGL_MOD_SHIFT)) { + puglview->specialFunc(puglview, mods & PUGL_MOD_SHIFT, PUGL_KEY_SHIFT); + } else if ((mods & PUGL_MOD_CTRL) != (puglview->mods & PUGL_MOD_CTRL)) { + puglview->specialFunc(puglview, mods & PUGL_MOD_CTRL, PUGL_KEY_CTRL); + } else if ((mods & PUGL_MOD_ALT) != (puglview->mods & PUGL_MOD_ALT)) { + puglview->specialFunc(puglview, mods & PUGL_MOD_ALT, PUGL_KEY_ALT); + } else if ((mods & PUGL_MOD_SUPER) != (puglview->mods & PUGL_MOD_SUPER)) { + puglview->specialFunc(puglview, mods & PUGL_MOD_SUPER, PUGL_KEY_SUPER); + } + puglview->mods = mods; + } +} + +@end +#endif + +#ifdef PUGL_HAVE_CAIRO +@interface PuglCairoView : NSView +{ + PuglView* puglview; + cairo_t* cr; + NSTrackingArea* trackingArea; +} + +- (PuglView *) puglView; +- (void) setPuglview:(PuglView *)pv; + +- (cairo_t *) cairoContext; + +- (BOOL) acceptsFirstMouse:(NSEvent*)e; +- (BOOL) acceptsFirstResponder; +- (BOOL) isFlipped; +- (BOOL) isOpaque; +- (BOOL) preservesContentInLiveResize; +- (id) initWithFrame:(NSRect)frame; +- (void) reshape; +- (void) drawRect:(NSRect)r; +/* TODO: duplication of code from PuglOpenGLView */ +- (void) cursorUpdate:(NSEvent*)e; +- (void) updateTrackingAreas; +- (void) viewWillMoveToWindow:(NSWindow*)newWindow; +- (void) mouseMoved:(NSEvent*)event; +- (void) mouseDragged:(NSEvent*)event; +- (void) rightMouseDragged:(NSEvent*)event; +- (void) otherMouseDragged:(NSEvent*)event; +- (void) mouseDown:(NSEvent*)event; +- (void) rightMouseDown:(NSEvent*)event; +- (void) otherMouseDown:(NSEvent*)event; +- (void) mouseUp:(NSEvent*)event; +- (void) rightMouseUp:(NSEvent*)event; +- (void) otherMouseUp:(NSEvent*)event; +- (void) scrollWheel:(NSEvent*)event; +- (void) keyDown:(NSEvent*)event; +- (void) keyUp:(NSEvent*)event; +- (void) flagsChanged:(NSEvent*)event; +@end + +@implementation PuglCairoView +- (PuglView *) puglView { + return self->puglview; +} + +- (void) setPuglview:(PuglView *)pv { + self->puglview = pv; +} + +- (cairo_t *) cairoContext { + return cr; +} + +- (BOOL) acceptsFirstMouse:(NSEvent*)e +{ + return YES; + + // unused + (void)e; +} + +- (BOOL) acceptsFirstResponder +{ + return YES; +} + +- (BOOL) isFlipped +{ + return YES; +} + +- (BOOL) isOpaque +{ + return YES; +} + +- (BOOL) preservesContentInLiveResize +{ + return NO; +} + +- (id) initWithFrame:(NSRect)frame { + puglview = nil; + cr = NULL; + trackingArea = nil; + [super initWithFrame:frame]; + return self; +} + +- (void) reshape +{ + if (!puglview) { + /* NOTE: Apparently reshape gets called when the GC gets around to + deleting the view (?), so we must have reset puglview to NULL when + this comes around. + */ + return; + } + + NSRect bounds = [self bounds]; + int width = bounds.size.width; + int height = bounds.size.height; + + puglEnterContext(puglview); + + if (puglview->reshapeFunc) { + puglview->reshapeFunc(puglview, width, height); + } else { + puglDefaultReshape(width, height); + } + + puglLeaveContext(puglview, false); + + puglview->width = width; + puglview->height = height; +} + +- (void) drawRect:(NSRect)r { + CGContextRef ctx = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort]; + NSRect bounds = [self bounds]; + cairo_surface_t* surface; + cairo_t* cairo; + + surface = cairo_quartz_surface_create_for_cg_context(ctx, bounds.size.width, bounds.size.height); + if (surface) { + cairo = cairo_create(surface); + if (cairo) { + self->cr = cairo; + puglEnterContext(puglview); + puglDisplay(puglview); + puglLeaveContext(puglview, true); + self->cr = NULL; + cairo_destroy(cairo); + } + cairo_surface_destroy(surface); + } +} + +- (void) cursorUpdate:(NSEvent*)e +{ + [[NSCursor arrowCursor] set]; + + // unused + return; (void)e; +} + +- (void) updateTrackingAreas +{ + static const int opts = NSTrackingMouseEnteredAndExited + | NSTrackingMouseMoved + | NSTrackingEnabledDuringMouseDrag + | NSTrackingInVisibleRect + | NSTrackingActiveAlways + | NSTrackingCursorUpdate; + + if (trackingArea != nil) { + [self removeTrackingArea:trackingArea]; + [trackingArea release]; + } + + trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds] + options:opts + owner:self + userInfo:nil]; + [self addTrackingArea:trackingArea]; + [super updateTrackingAreas]; +} + +- (void) viewWillMoveToWindow:(NSWindow*)newWindow +{ + if (newWindow != nil) { + [newWindow setAcceptsMouseMovedEvents:YES]; + [newWindow makeFirstResponder:self]; + } + + [super viewWillMoveToWindow:newWindow]; +} + - (void) mouseMoved:(NSEvent*)event { if (puglview->motionFunc) { @@ -410,11 +721,19 @@ getFixedAppKitButton(NSInteger button) puglview->mods = mods; } } - @end +#endif struct PuglInternalsImpl { - PuglOpenGLView* glview; + union { + NSView* view; +#ifdef PUGL_HAVE_GL + PuglOpenGLView* glview; +#endif +#ifdef PUGL_HAVE_CAIRO + PuglCairoView* cairoview; +#endif + }; id window; }; @@ -427,13 +746,18 @@ puglInitInternals() void puglEnterContext(PuglView* view) { - [[view->impl->glview openGLContext] makeCurrentContext]; +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + [[view->impl->glview openGLContext] makeCurrentContext]; + } +#endif } void puglLeaveContext(PuglView* view, bool flush) { - if (flush) { +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL && flush) { if (view->impl->glview->doubleBuffered) { [[view->impl->glview openGLContext] flushBuffer]; } else { @@ -441,6 +765,7 @@ puglLeaveContext(PuglView* view, bool flush) } //[NSOpenGLContext clearCurrentContext]; } +#endif } int @@ -451,22 +776,31 @@ puglCreateWindow(PuglView* view, const char* title) [NSAutoreleasePool new]; [NSApplication sharedApplication]; - impl->glview = [PuglOpenGLView new]; +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + impl->glview = [PuglOpenGLView new]; + } +#endif +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + impl->cairoview = [PuglCairoView new]; + } +#endif - if (!impl->glview) { + if (!impl->view) { return 1; } - - impl->glview->puglview = view; + + [impl->view setPuglview:view]; if (view->user_resizable) { - [impl->glview setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; + [impl->view setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable]; } if (view->parent) { - [impl->glview retain]; + [impl->view retain]; NSView* pview = (NSView*)view->parent; - [pview addSubview:impl->glview]; + [pview addSubview:impl->view]; return 0; } @@ -482,8 +816,8 @@ puglCreateWindow(PuglView* view, const char* title) } [window setPuglview:view]; - [window setContentView:impl->glview]; - [window makeFirstResponder:impl->glview]; + [window setContentView:impl->view]; + [window makeFirstResponder:impl->view]; [window makeKeyAndOrderFront:window]; // wait for first puglShowWindow @@ -505,7 +839,7 @@ puglShowWindow(PuglView* view) if (impl->window) { [impl->window setIsVisible:YES]; } else { - [view->impl->glview setHidden:NO]; + [view->impl->view setHidden:NO]; } } @@ -517,21 +851,21 @@ puglHideWindow(PuglView* view) if (impl->window) { [impl->window setIsVisible:NO]; } else { - [impl->glview setHidden:YES]; + [impl->view setHidden:YES]; } } void puglDestroy(PuglView* view) { - view->impl->glview->puglview = NULL; + [view->impl->view setPuglview:NULL]; if (view->impl->window) { [view->impl->window close]; - [view->impl->glview release]; + [view->impl->view release]; [view->impl->window release]; } else { - [view->impl->glview release]; + [view->impl->view release]; } free(view->impl); @@ -551,13 +885,27 @@ void puglPostRedisplay(PuglView* view) { view->redisplay = true; - [view->impl->glview setNeedsDisplay:YES]; + [view->impl->view setNeedsDisplay:YES]; } PuglNativeWindow puglGetNativeWindow(PuglView* view) { - return (PuglNativeWindow)view->impl->glview; + return (PuglNativeWindow)view->impl->view; +} + +void* +puglGetContext(PuglView* view) +{ +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + return [view->impl->cairoview cairoContext]; + } +#endif + return NULL; + + // may be unused + (void)view; } int diff --git a/dgl/src/pugl/pugl_win.cpp b/dgl/src/pugl/pugl_win.cpp index 9990b8ef..e8b2612f 100644 --- a/dgl/src/pugl/pugl_win.cpp +++ b/dgl/src/pugl/pugl_win.cpp @@ -21,7 +21,13 @@ #include #include #include +#ifdef PUGL_HAVE_GL #include +#endif +#ifdef PUGL_HAVE_CAIRO +#include +#include +#endif #include #include @@ -48,8 +54,13 @@ HINSTANCE hInstance = NULL; struct PuglInternalsImpl { HWND hwnd; +#ifdef PUGL_HAVE_GL HDC hdc; HGLRC hglrc; +#endif +#ifdef PUGL_HAVE_CAIRO + cairo_t* cr; +#endif WNDCLASS wc; }; @@ -76,17 +87,25 @@ puglInitInternals() void puglEnterContext(PuglView* view) { - wglMakeCurrent(view->impl->hdc, view->impl->hglrc); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + wglMakeCurrent(view->impl->hdc, view->impl->hglrc); + } +#endif } void puglLeaveContext(PuglView* view, bool flush) { - if (flush) { - glFlush(); - SwapBuffers(view->impl->hdc); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + if (flush) { + glFlush(); + SwapBuffers(view->impl->hdc); + } + wglMakeCurrent(NULL, NULL); } - wglMakeCurrent(NULL, NULL); +#endif } int @@ -124,7 +143,6 @@ puglCreateWindow(PuglView* view, const char* title) if (!RegisterClass(&impl->wc)) { free((void*)impl->wc.lpszClassName); free(impl); - free(view); return 1; } @@ -155,37 +173,39 @@ puglCreateWindow(PuglView* view, const char* title) UnregisterClass(impl->wc.lpszClassName, NULL); free((void*)impl->wc.lpszClassName); free(impl); - free(view); return 1; } SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view); - impl->hdc = GetDC(impl->hwnd); - - PIXELFORMATDESCRIPTOR pfd; - ZeroMemory(&pfd, sizeof(pfd)); - pfd.nSize = sizeof(pfd); - pfd.nVersion = 1; - pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = 24; - pfd.cDepthBits = 16; - pfd.iLayerType = PFD_MAIN_PLANE; - - int format = ChoosePixelFormat(impl->hdc, &pfd); - SetPixelFormat(impl->hdc, format, &pfd); - - impl->hglrc = wglCreateContext(impl->hdc); - if (!impl->hglrc) { - ReleaseDC (impl->hwnd, impl->hdc); - DestroyWindow (impl->hwnd); - UnregisterClass (impl->wc.lpszClassName, NULL); - free((void*)impl->wc.lpszClassName); - free(impl); - free(view); - return 1; +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + impl->hdc = GetDC(impl->hwnd); + + PIXELFORMATDESCRIPTOR pfd; + ZeroMemory(&pfd, sizeof(pfd)); + pfd.nSize = sizeof(pfd); + pfd.nVersion = 1; + pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER; + pfd.iPixelType = PFD_TYPE_RGBA; + pfd.cColorBits = 24; + pfd.cDepthBits = 16; + pfd.iLayerType = PFD_MAIN_PLANE; + + int format = ChoosePixelFormat(impl->hdc, &pfd); + SetPixelFormat(impl->hdc, format, &pfd); + + impl->hglrc = wglCreateContext(impl->hdc); + if (!impl->hglrc) { + ReleaseDC (impl->hwnd, impl->hdc); + DestroyWindow (impl->hwnd); + UnregisterClass (impl->wc.lpszClassName, NULL); + free((void*)impl->wc.lpszClassName); + free(impl); + return 1; + } } +#endif return PUGL_SUCCESS; } @@ -205,13 +225,23 @@ puglHideWindow(PuglView* view) void puglDestroy(PuglView* view) { - wglMakeCurrent(NULL, NULL); - wglDeleteContext(view->impl->hglrc); - ReleaseDC(view->impl->hwnd, view->impl->hdc); - DestroyWindow(view->impl->hwnd); - UnregisterClass(view->impl->wc.lpszClassName, NULL); - free((void*)view->impl->wc.lpszClassName); - free(view->impl); + if (!view) { + return; + } + + PuglInternals* const impl = view->impl; + +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + wglMakeCurrent(NULL, NULL); + wglDeleteContext(impl->hglrc); + } + ReleaseDC(impl->hwnd, impl->hdc); +#endif + DestroyWindow(impl->hwnd); + UnregisterClass(impl->wc.lpszClassName, NULL); + free((void*)impl->wc.lpszClassName); + free(impl); free(view); } @@ -329,9 +359,32 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam) mmi->ptMinTrackSize.y = view->min_height; break; case WM_PAINT: - BeginPaint(view->impl->hwnd, &ps); - puglDisplay(view); - EndPaint(view->impl->hwnd, &ps); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + BeginPaint(view->impl->hwnd, &ps); + puglDisplay(view); + EndPaint(view->impl->hwnd, &ps); + } +#endif +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + HDC hdc = BeginPaint(view->impl->hwnd, &ps); + if (hdc == NULL) + break; + cairo_surface_t *surface = cairo_win32_surface_create(hdc); + if (surface) { + cairo_t *cr = cairo_create(surface); + if (cr) { + view->impl->cr = cr; + puglDisplay(view); + view->impl->cr = NULL; + cairo_destroy(cr); + } + cairo_surface_destroy(surface); + } + EndPaint(view->impl->hwnd, &ps); + } +#endif break; case WM_MOUSEMOVE: if (view->motionFunc) { @@ -469,6 +522,20 @@ puglGetNativeWindow(PuglView* view) return (PuglNativeWindow)view->impl->hwnd; } +void* +puglGetContext(PuglView* view) +{ +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + return view->impl->cr; + } +#endif + return NULL; + + // may be unused + (void)view; +} + int puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect) { diff --git a/dgl/src/pugl/pugl_x11.c b/dgl/src/pugl/pugl_x11.c index ea70db1d..20f86b73 100644 --- a/dgl/src/pugl/pugl_x11.c +++ b/dgl/src/pugl/pugl_x11.c @@ -24,8 +24,14 @@ #include #include +#ifdef PUGL_HAVE_GL #include #include +#endif +#ifdef PUGL_HAVE_CAIRO +#include +#include +#endif #include #include #include @@ -53,10 +59,17 @@ struct PuglInternalsImpl { Display* display; int screen; Window win; +#ifdef PUGL_HAVE_CAIRO + cairo_t* cr; + cairo_surface_t* surface; +#endif +#ifdef PUGL_HAVE_GL GLXContext ctx; Bool doubleBuffered; +#endif }; +#ifdef PUGL_HAVE_GL /** Attributes for single-buffered RGBA with at least 4 bits per color and a 16 bit depth buffer. @@ -102,6 +115,7 @@ static int attrListDblMS[] = { GLX_SAMPLES, 4, None }; +#endif PuglInternals* puglInitInternals(void) @@ -112,25 +126,33 @@ puglInitInternals(void) void puglEnterContext(PuglView* view) { - glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx); + } +#endif } void puglLeaveContext(PuglView* view, bool flush) { - if (flush) { - glFlush(); - if (view->impl->doubleBuffered) { - glXSwapBuffers(view->impl->display, view->impl->win); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + if (flush) { + glFlush(); + if (view->impl->doubleBuffered) { + glXSwapBuffers(view->impl->display, view->impl->win); + } } + glXMakeCurrent(view->impl->display, None, NULL); } - glXMakeCurrent(view->impl->display, None, NULL); +#endif } int puglCreateWindow(PuglView* view, const char* title) { - PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals)); + PuglInternals* impl = view->impl; if (!impl) { return 1; } @@ -142,21 +164,35 @@ puglCreateWindow(PuglView* view, const char* title) return 1; } impl->screen = DefaultScreen(impl->display); - impl->doubleBuffered = True; - XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS); + XVisualInfo* vi = NULL; - if (!vi) { - vi = glXChooseVisual(impl->display, impl->screen, attrListDbl); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + impl->doubleBuffered = True; + vi = glXChooseVisual(impl->display, impl->screen, attrListDblMS); + + if (!vi) { + vi = glXChooseVisual(impl->display, impl->screen, attrListDbl); #ifdef PUGL_VERBOSE - printf("puGL: multisampling (antialiasing) is not available\n"); + printf("puGL: multisampling (antialiasing) is not available\n"); #endif - } + } - if (!vi) { - vi = glXChooseVisual(impl->display, impl->screen, attrListSgl); - impl->doubleBuffered = False; + if (!vi) { + vi = glXChooseVisual(impl->display, impl->screen, attrListSgl); + impl->doubleBuffered = False; + } } +#endif +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + XVisualInfo pat; + int n; + pat.screen = impl->screen; + vi = XGetVisualInfo(impl->display, VisualScreenMask, &pat, &n); + } +#endif if (!vi) { XCloseDisplay(impl->display); @@ -165,18 +201,25 @@ puglCreateWindow(PuglView* view, const char* title) } #ifdef PUGL_VERBOSE +#ifdef PUGL_HAVE_GL int glxMajor, glxMinor; glXQueryVersion(impl->display, &glxMajor, &glxMinor); printf("puGL: GLX-Version : %d.%d\n", glxMajor, glxMinor); #endif +#endif - impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE); - if (!impl->ctx) { - XCloseDisplay(impl->display); - free(impl); - return 1; + if (!impl->ctx) { + XFree(vi); + XCloseDisplay(impl->display); + free(impl); + return 1; + } } +#endif Window xParent = view->parent ? (Window)view->parent @@ -201,11 +244,40 @@ puglCreateWindow(PuglView* view, const char* title) CWBorderPixel | CWColormap | CWEventMask, &attr); if (!impl->win) { +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + glXDestroyContext(impl->display, impl->ctx); + } +#endif + XFree(vi); XCloseDisplay(impl->display); free(impl); return 1; } +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + impl->surface = cairo_xlib_surface_create( + impl->display, impl->win, vi->visual, view->width, view->height); + if (impl->surface == NULL || cairo_surface_status(impl->surface) != CAIRO_STATUS_SUCCESS) { + printf("puGL: failed to create cairo surface\n"); + } + else { + impl->cr = cairo_create(impl->surface); + } + if (impl->cr == NULL || cairo_status(impl->cr) != CAIRO_STATUS_SUCCESS) { + cairo_destroy(impl->cr); + cairo_surface_destroy(impl->surface); + XDestroyWindow(impl->display, impl->win); + XFree(vi); + XCloseDisplay(impl->display); + free(impl); + printf("puGL: failed to create cairo context\n"); + return 1; + } + } +#endif + if (view->width > 1 || view->height > 1) { puglUpdateGeometryConstraints(view, view->min_width, view->min_height, view->min_width != view->width); XResizeWindow(view->impl->display, view->impl->win, view->width, view->height); @@ -227,11 +299,13 @@ puglCreateWindow(PuglView* view, const char* title) } #ifdef PUGL_VERBOSE +#ifdef PUGL_HAVE_GL if (glXIsDirect(impl->display, impl->ctx)) { printf("puGL: DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n"); } else { printf("puGL: No DRI available\n"); } +#endif #endif XFree(vi); @@ -244,14 +318,27 @@ puglDestroy(PuglView* view) if (!view) { return; } + + PuglInternals* const impl = view->impl; + #ifndef DGL_FILE_BROWSER_DISABLED - x_fib_close(view->impl->display); + x_fib_close(impl->display); #endif - glXDestroyContext(view->impl->display, view->impl->ctx); - XDestroyWindow(view->impl->display, view->impl->win); - XCloseDisplay(view->impl->display); - free(view->impl); +#ifdef PUGL_HAVE_GL + if (view->ctx_type == PUGL_GL) { + glXDestroyContext(impl->display, impl->ctx); + } +#endif +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + cairo_destroy(impl->cr); + cairo_surface_destroy(impl->surface); + } +#endif + XDestroyWindow(impl->display, impl->win); + XCloseDisplay(impl->display); + free(impl); free(view); } @@ -554,6 +641,14 @@ puglProcessEvents(PuglView* view) } if (conf_width != -1) { +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + // Resize surfaces/contexts before dispatching + view->redisplay = true; + cairo_xlib_surface_set_size(view->impl->surface, + conf_width, conf_height); + } +#endif puglReshape(view, conf_width, conf_height); } @@ -586,6 +681,20 @@ puglGetNativeWindow(PuglView* view) return view->impl->win; } +void* +puglGetContext(PuglView* view) +{ +#ifdef PUGL_HAVE_CAIRO + if (view->ctx_type == PUGL_CAIRO) { + return view->impl->cr; + } +#endif + return NULL; + + // may be unused + (void)view; +} + int puglUpdateGeometryConstraints(PuglView* view, int min_width, int min_height, bool aspect) { diff --git a/distrho/src/DistrhoPluginChecks.h b/distrho/src/DistrhoPluginChecks.h index 24f25d8e..0d2fc94c 100644 --- a/distrho/src/DistrhoPluginChecks.h +++ b/distrho/src/DistrhoPluginChecks.h @@ -93,7 +93,7 @@ // Define DISTRHO_PLUGIN_HAS_EMBED_UI if needed #ifndef DISTRHO_PLUGIN_HAS_EMBED_UI -# ifdef HAVE_DGL +# if defined(HAVE_DGL) || defined(HAVE_DCAIRO) # define DISTRHO_PLUGIN_HAS_EMBED_UI 1 # else # define DISTRHO_PLUGIN_HAS_EMBED_UI 0 @@ -135,7 +135,7 @@ // ----------------------------------------------------------------------- // Disable UI if DGL or External UI is not available -#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI && ! defined(HAVE_DGL) +#if DISTRHO_PLUGIN_HAS_UI && ! DISTRHO_PLUGIN_HAS_EXTERNAL_UI && ! defined(HAVE_DGL) && ! defined(HAVE_DCAIRO) # undef DISTRHO_PLUGIN_HAS_UI # define DISTRHO_PLUGIN_HAS_UI 0 #endif diff --git a/distrho/src/DistrhoUI.cpp b/distrho/src/DistrhoUI.cpp index a9502161..c1f80ba3 100644 --- a/distrho/src/DistrhoUI.cpp +++ b/distrho/src/DistrhoUI.cpp @@ -152,6 +152,7 @@ void UI::uiFileBrowserSelected(const char*) void UI::uiReshape(uint width, uint height) { +#if defined(HAVE_DGL) glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glMatrixMode(GL_PROJECTION); @@ -160,6 +161,7 @@ void UI::uiReshape(uint width, uint height) glViewport(0, 0, static_cast(width), static_cast(height)); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); +#endif } /* ------------------------------------------------------------------------------------------------------------