From 0531409611867ae8dad711e52d6534fa634d40cc Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 10 Sep 2017 17:52:32 +0200 Subject: Initial steps towards pugl domination! --- plugingui/Makefile.am | 38 +++- plugingui/nativewindow.h | 4 +- plugingui/nativewindow_pugl.cc | 372 +++++++++++++++++++++++++++------------- plugingui/nativewindow_pugl.h | 45 +++-- plugingui/nativewindow_win32.cc | 4 +- plugingui/nativewindow_win32.h | 4 +- plugingui/nativewindow_x11.cc | 29 +--- plugingui/nativewindow_x11.h | 4 +- 8 files changed, 327 insertions(+), 173 deletions(-) (limited to 'plugingui') diff --git a/plugingui/Makefile.am b/plugingui/Makefile.am index 714b21c..f9d9c09 100644 --- a/plugingui/Makefile.am +++ b/plugingui/Makefile.am @@ -42,6 +42,8 @@ libdggui_la_CPPFLAGS = \ -DLODEPNG_NO_COMPILE_ERROR_TEXT \ -DLODEPNG_NO_COMPILE_CPP +libdggui_la_CFLAGS = + libdggui_la_LIBADD = \ $(GUI_LIBS) $(PTHREAD_LIBS) @@ -110,18 +112,42 @@ nodist_libdggui_la_SOURCES += \ nativewindow_win32.cc endif -if ENABLE_PUGL -nodist_libdggui_la_SOURCES += \ - nativewindow_pugl.cc \ - $(top_srcdir)/pugl/pugl/pugl_x11.c -endif - #if ENABLE_COCOA #nodist_libdggui_la_SOURCES += \ # nativewindow_cocoa.m \ # nativewindow_cocoa.cc #endif +if ENABLE_PUGL_X11 +nodist_libdggui_la_SOURCES += \ + nativewindow_pugl.cc \ + $(top_srcdir)/pugl/pugl/pugl_x11.c + +libdggui_la_CPPFLAGS += \ + -I$(top_srcdir)/pugl + +libdggui_la_CFLAGS += \ + -std=c99 +endif + +if ENABLE_PUGL_WIN32 +nodist_libdggui_la_SOURCES += \ + nativewindow_pugl.cc \ + $(top_srcdir)/pugl/pugl/pugl_win.cpp + +libdggui_la_CPPFLAGS += \ + -I$(top_srcdir)/pugl +endif + +if ENABLE_PUGL_COCOA +nodist_libdggui_la_SOURCES += \ + nativewindow_pugl.cc \ + $(top_srcdir)/pugl/pugl/pugl_osx.m + +libdggui_la_CPPFLAGS += \ + -I$(top_srcdir)/pugl +endif + plugingui_LDADD = libdggui.la $(top_srcdir)/src/libdg.la plugingui_CXXFLAGS = $(SNDFILE_CXXFLAGS) $(PTHREAD_CFLAGS) $(EXPAT_CFLAGS) \ diff --git a/plugingui/nativewindow.h b/plugingui/nativewindow.h index 6dcb308..3995d43 100644 --- a/plugingui/nativewindow.h +++ b/plugingui/nativewindow.h @@ -52,7 +52,7 @@ public: virtual void resize(std::size_t width, std::size_t height) = 0; //! Query size of the native window. - virtual std::pair getSize() = 0; + virtual std::pair getSize() const = 0; //! Move the window to a new position. //! Note: negative value are allowed. @@ -60,7 +60,7 @@ public: //! Query the screen position of the native window. //! Note: returned values can be negative. - virtual std::pair getPosition() = 0; + virtual std::pair getPosition() const = 0; //! Show the window if it is hidden. virtual void show() = 0; diff --git a/plugingui/nativewindow_pugl.cc b/plugingui/nativewindow_pugl.cc index d7cca54..59f03b1 100644 --- a/plugingui/nativewindow_pugl.cc +++ b/plugingui/nativewindow_pugl.cc @@ -42,46 +42,284 @@ #include -namespace GUI { +namespace GUI +{ + +NativeWindowPugl::NativeWindowPugl(void* native_window, Window& window) + : window(window) +{ + INFO(nativewindow, "Running with PuGL native window\n"); + view = puglInit(nullptr, nullptr); + puglInitContextType(view, PUGL_GL); + if(native_window) + { + puglInitWindowParent(view, (PuglNativeWindow)native_window); + } + puglInitWindowClass(view, "DrumgGizmo"); + puglInitWindowSize(view, 750, 466); + puglInitResizable(view, true); + puglCreateWindow(view, "DrumGizmo"); + + puglSetHandle(view, (PuglHandle)this); + puglSetEventFunc(view, onEvent); +} + +NativeWindowPugl::~NativeWindowPugl() +{ + puglDestroy(view); +} + +void NativeWindowPugl::setFixedSize(std::size_t width, std::size_t height) +{ +// redraw(); +} + +void NativeWindowPugl::resize(std::size_t width, std::size_t height) +{ +// DEBUG(nativewindow_pugl, "Resizing to %dx%d\n", width, height); +// init(); +// redraw(); +} + +std::pair NativeWindowPugl::getSize() const +{ + int width, height; + puglGetSize(view, &width, &height); + return {width, height}; +} + +void NativeWindowPugl::move(int x, int y) +{ +// redraw(); +} + +void NativeWindowPugl::show() +{ + puglShowWindow(view); +} + +void NativeWindowPugl::hide() +{ + puglHideWindow(view); +} + +bool NativeWindowPugl::visible() const +{ + return puglGetVisible(view); +} + +void NativeWindowPugl::redraw(const Rect& dirty_rect) +{ + //puglPostRedisplay(view);// handleBuffer(); + onDisplay(view); +} + +void NativeWindowPugl::setCaption(const std::string &caption) +{ +// redraw(); +} + +void NativeWindowPugl::grabMouse(bool grab) +{ + puglGrabFocus(view); +} + +EventQueue NativeWindowPugl::getEvents() +{ + puglProcessEvents(view); + EventQueue events; + std::swap(events, event_queue); + return events; +} + +void* NativeWindowPugl::getNativeWindowHandle() const +{ + return (void*)puglGetNativeWindow(view); +} + +void NativeWindowPugl::onEvent(PuglView* view, const PuglEvent* event) +{ + NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view); + + switch(event->type) + { + case PUGL_NOTHING: + break; + case PUGL_CONFIGURE: + onReshape(view, event->configure.width, event->configure.height); + { + auto resize_event = std::make_shared(); + resize_event->width = event->configure.width; + resize_event->height = event->configure.height; + native->event_queue.push_back(resize_event); + } + break; + case PUGL_EXPOSE: + onDisplay(view); + break; + case PUGL_CLOSE: + //quit = 1; + break; + case PUGL_KEY_PRESS: + fprintf(stderr, "Key %u (char %u) press (%s)%s\n", + event->key.keycode, event->key.character, event->key.utf8, + event->key.filter ? " (filtered)" : ""); + if (event->key.character == 'q' || + event->key.character == 'Q' || + event->key.character == PUGL_CHAR_ESCAPE) { + //quit = 1; + } + break; + case PUGL_KEY_RELEASE: + fprintf(stderr, "Key %u (char %u) release (%s)%s\n", + event->key.keycode, event->key.character, event->key.utf8, + event->key.filter ? " (filtered)" : ""); + break; + case PUGL_MOTION_NOTIFY: + { + auto mouseMoveEvent = std::make_shared(); + mouseMoveEvent->x = event->motion.x; + mouseMoveEvent->y = event->motion.y; + native->event_queue.push_back(mouseMoveEvent); + } + break; + case PUGL_BUTTON_PRESS: + case PUGL_BUTTON_RELEASE: + { + auto buttonEvent = std::make_shared(); + buttonEvent->x = event->button.x; + buttonEvent->y = event->button.y; + switch(event->button.button) { + case 1: + buttonEvent->button = MouseButton::left; + break; + case 2: + buttonEvent->button = MouseButton::middle; + break; + case 3: + buttonEvent->button = MouseButton::right; + break; + default: + WARN(X11, "Unknown button %d, setting to MouseButton::left\n", + event->button.button); + buttonEvent->button = MouseButton::left; + break; + } + + buttonEvent->direction = + (event->type == PUGL_BUTTON_PRESS) ? + Direction::down : Direction::up; + + buttonEvent->doubleClick = + (event->type == PUGL_BUTTON_PRESS) && + ((event->button.time - native->last_click) < 200); + + if(event->type == PUGL_BUTTON_PRESS) + { + native->last_click = event->button.time; + } + native->event_queue.push_back(buttonEvent); + } + fprintf(stderr, "Mouse %d %s at %f,%f ", + event->button.button, + (event->type == PUGL_BUTTON_PRESS) ? "down" : "up", + event->button.x, + event->button.y); + ///printModifiers(view, event->scroll.state); + break; + case PUGL_SCROLL: + { + auto scrollEvent = std::make_shared(); + scrollEvent->x = event->scroll.x; + scrollEvent->y = event->scroll.y; + scrollEvent->delta = event->scroll.dy * -1;//scroll * ((xevent.xbutton.button == 4) ? -1 : 1); + native->event_queue.push_back(scrollEvent); + } + fprintf(stderr, "Scroll %f %f %f %f ", + event->scroll.x, event->scroll.y, event->scroll.dx, event->scroll.dy); + //printModifiers(view, event->scroll.state); + //dist += event->scroll.dy; + //if (dist < 10.0f) { + // dist = 10.0f; + //} + puglPostRedisplay(view); + break; + case PUGL_ENTER_NOTIFY: + fprintf(stderr, "Entered\n"); + break; + case PUGL_LEAVE_NOTIFY: + fprintf(stderr, "Exited\n"); + break; + case PUGL_FOCUS_IN: + fprintf(stderr, "Focus in\n"); + break; + case PUGL_FOCUS_OUT: + fprintf(stderr, "Focus out\n"); + break; + } +} + +void NativeWindowPugl::onReshape(PuglView* view, int width, int height) +{ + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glViewport(0, 0, width, height); +} void NativeWindowPugl::onDisplay(PuglView* view) { NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view); Window& window = native->window; + //window.redraw(); + + printf("!!! %p %d %d\n", native, (int)window.wpixbuf.width, (int)window.wpixbuf.height); + if((window.wpixbuf.width < 16) || (window.wpixbuf.height < 16)) + { + return; + } + + puglEnterContext(view); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0f, 0.0f, 0.0f); + GLuint image; glGenTextures(1, &image); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + //glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); //GL_NEAREST = no smoothing - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE, GL_REPLACE); glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, window.wpixbuf.width, - window.wpixbuf.height, 0, GL_RGB, GL_UNSIGNED_BYTE, + glTexImage2D(GL_TEXTURE_2D, + 0, GL_RGBA, + window.wpixbuf.width, + window.wpixbuf.height, + 0, GL_RGB, GL_UNSIGNED_BYTE, window.wpixbuf.buf); glEnable(GL_TEXTURE_2D); glBegin(GL_QUADS); - glTexCoord2d(0.0, 0.0); glVertex2f(0.0, 0.0); - glTexCoord2d(0.0, 1.0); glVertex2f(0.0, window.wpixbuf.height); - glTexCoord2d(1.0, 1.0); glVertex2f(window.wpixbuf.width, window.wpixbuf.height); - glTexCoord2d(1.0, 0.0); glVertex2f(window.wpixbuf.width, 0.0); + glTexCoord2d(0.0f, 0.0f); glVertex2f(-1.0f, -1.0f); + glTexCoord2d(0.0f, -1.0f); glVertex2f(-1.0f, 1.0f); + glTexCoord2d(1.0f, -1.0f); glVertex2f( 1.0f, 1.0f); + glTexCoord2d(1.0f, 0.0f); glVertex2f( 1.0f, -1.0f); glEnd(); glDeleteTextures(1, &image); glDisable(GL_TEXTURE_2D); glFlush(); - puglPostRedisplay(view); + puglLeaveContext(view, true); } void NativeWindowPugl::onMouse(PuglView* view, int button, bool press, int x, int y) @@ -145,114 +383,4 @@ void NativeWindowPugl::onKeyboard(PuglView* view, bool press, uint32_t key) native->eventq.push_back(e); } -NativeWindowPugl::NativeWindowPugl(void* native_window, Window& window) - : window(window) - , native_window(native_window) -{ - INFO(nativewindow, "Running with PuGL native window\n"); - init(); -} - -NativeWindowPugl::~NativeWindowPugl() -{ - puglDestroy(view); -} - -void NativeWindowPugl::init() -{ - PuglView* oldView = view; - if(view) - { - oldView = view; - } - -// view = puglCreate(0, "DrumgGizmo", window.x(), window.y(), false, true); - view = puglCreate((PuglNativeWindow)native_window, "DrumgGizmo", 370, 330, false, true); - puglSetHandle(view, (PuglHandle)this); - puglSetDisplayFunc(view, onDisplay); - puglSetMouseFunc(view, onMouse); - puglSetKeyboardFunc(view, onKeyboard); - - if(oldView) - { - free(oldView); - } -} - -void NativeWindowPugl::setFixedSize(int width, int height) -{ -// redraw(); -} - -void NativeWindowPugl::resize(int width, int height) -{ -// DEBUG(nativewindow_pugl, "Resizing to %dx%d\n", width, height); -// init(); -// redraw(); -} - -void NativeWindowPugl::move(int x, int y) -{ -// redraw(); -} - -void NativeWindowPugl::show() -{ -// redraw(); -} - -void NativeWindowPugl::hide() -{ -// redraw(); -} - -void NativeWindowPugl::handleBuffer() -{ - onDisplay(view); -} - -void NativeWindowPugl::redraw() -{ -// handleBuffer(); -} - -void NativeWindowPugl::setCaption(const std::string &caption) -{ -// redraw(); -} - -void NativeWindowPugl::grabMouse(bool grab) -{ -// redraw(); -} - -bool NativeWindowPugl::hasEvent() -{ - // dirty hack - assume that this function is called enough times to get fluent gui - // ^^ Bad assumption - puglProcessEvents(view); - return !eventq.empty(); -} - -Event *NativeWindowPugl::getNextEvent() -{ - Event *event = nullptr; - - if(!eventq.empty()) { - event = eventq.front(); - eventq.pop_front(); - } - return event; -} - -Event *NativeWindowPugl::peekNextEvent() -{ - Event *event = nullptr; - - if(!eventq.empty()) { - event = eventq.front(); - } - return event; -} - } // GUI:: diff --git a/plugingui/nativewindow_pugl.h b/plugingui/nativewindow_pugl.h index 000a48b..6a667f4 100644 --- a/plugingui/nativewindow_pugl.h +++ b/plugingui/nativewindow_pugl.h @@ -27,11 +27,15 @@ #pragma once #include "nativewindow.h" -#include "pugl.h" +extern "C" +{ +#include +} #include -namespace GUI { +namespace GUI +{ class Event; class Window; @@ -41,32 +45,39 @@ public: NativeWindowPugl(void* native_window, Window& window); ~NativeWindowPugl(); - void init(); - void setFixedSize(int width, int height); - void resize(int width, int height); - void move(int x, int y); - void show(); - void setCaption(const std::string &caption); - void hide(); - void handleBuffer(); - void redraw(); - void grabMouse(bool grab); - - bool hasEvent(); - Event *getNextEvent(); - Event *peekNextEvent(); + void setFixedSize(std::size_t width, std::size_t height) override; + void resize(std::size_t width, std::size_t height) override; + std::pair getSize() const override; + + void move(int x, int y) override; + std::pair getPosition() const override{ return {}; } + + void show() override; + void setCaption(const std::string &caption) override; + void hide() override; + bool visible() const override; + void redraw(const Rect& dirty_rect) override; + void grabMouse(bool grab) override; + + EventQueue getEvents() override; + + void* getNativeWindowHandle() const override; private: Window& window; - void* native_window{nullptr}; PuglView* view{nullptr}; std::list eventq; // Internal pugl c-callbacks + static void onEvent(PuglView* view, const PuglEvent* event); + static void onReshape(PuglView* view, int width, int height); static void onDisplay(PuglView* view); static void onMouse(PuglView* view, int button, bool press, int x, int y); static void onKeyboard(PuglView* view, bool press, uint32_t key); + + EventQueue event_queue; + std::uint32_t last_click{0}; }; } // GUI:: diff --git a/plugingui/nativewindow_win32.cc b/plugingui/nativewindow_win32.cc index 1de78fb..5cfb179 100644 --- a/plugingui/nativewindow_win32.cc +++ b/plugingui/nativewindow_win32.cc @@ -432,7 +432,7 @@ void NativeWindowWin32::resize(std::size_t width, std::size_t height) SetWindowPos(hwnd, nullptr, -1, -1, width + w, height + h, SWP_NOMOVE); } -std::pair NativeWindowWin32::getSize() +std::pair NativeWindowWin32::getSize() const { RECT rect; GetClientRect(m_hwnd, &rect); @@ -444,7 +444,7 @@ void NativeWindowWin32::move(int x, int y) SetWindowPos(m_hwnd, nullptr, (int)x, (int)y, -1, -1, SWP_NOSIZE); } -std::pair NativeWindowWin32::getPosition() +std::pair NativeWindowWin32::getPosition() const { RECT rect; GetClientRect(m_hwnd, &rect); diff --git a/plugingui/nativewindow_win32.h b/plugingui/nativewindow_win32.h index bb407d8..2945be6 100644 --- a/plugingui/nativewindow_win32.h +++ b/plugingui/nativewindow_win32.h @@ -46,9 +46,9 @@ public: void setFixedSize(std::size_t width, std::size_t height) override; void resize(std::size_t width, std::size_t height) override; - std::pair getSize() override; + std::pair getSize() const override; void move(int x, int y) override; - std::pair getPosition() override; + std::pair getPosition() const override; void show() override; bool visible() const override; void hide() override; diff --git a/plugingui/nativewindow_x11.cc b/plugingui/nativewindow_x11.cc index 5faecc1..056c69f 100644 --- a/plugingui/nativewindow_x11.cc +++ b/plugingui/nativewindow_x11.cc @@ -130,25 +130,14 @@ void NativeWindowX11::setFixedSize(std::size_t width, std::size_t height) resize(width, height); - XSizeHints* size_hints; - size_hints = XAllocSizeHints(); + XSizeHints size_hints; + memset(&size_hints, 0, sizeof(size_hints)); - if(size_hints == nullptr) - { - ERR(X11,"XMallocSizeHints() failed"); - return; - } - - size_hints->flags = USPosition | PMinSize | PMaxSize; - size_hints->min_width = size_hints->max_width = width; - size_hints->min_height = size_hints->max_height = height; - - //size_hints->min_aspect.x = (float)window.width()/(float)window.height(); - //size_hints->max_aspect.x = (float)window.width()/(float)window.height(); - //size_hints->min_aspect.y = (float)window.width()/(float)window.height(); - //size_hints->max_aspect.y = size_hints->min_aspect.y; + size_hints.flags = PMinSize|PMaxSize; + size_hints.min_width = size_hints.max_width = (int)width; + size_hints.min_height = size_hints.max_height = (int)height; - XSetWMNormalHints(display, xwindow, size_hints); + XSetNormalHints(display, xwindow, &size_hints); } void NativeWindowX11::resize(std::size_t width, std::size_t height) @@ -161,7 +150,7 @@ void NativeWindowX11::resize(std::size_t width, std::size_t height) XResizeWindow(display, xwindow, width, height); } -std::pair NativeWindowX11::getSize() +std::pair NativeWindowX11::getSize() const { // XWindowAttributes attributes; // XGetWindowAttributes(display, xwindow, &attributes); @@ -175,7 +164,7 @@ std::pair NativeWindowX11::getSize() &x, &y, &width, &height, &border, &depth); - return std::make_pair(width, height); + return {width, height}; } void NativeWindowX11::move(int x, int y) @@ -188,7 +177,7 @@ void NativeWindowX11::move(int x, int y) XMoveWindow(display, xwindow, x, y); } -std::pair NativeWindowX11::getPosition() +std::pair NativeWindowX11::getPosition() const { ::Window root_window; ::Window child_window; diff --git a/plugingui/nativewindow_x11.h b/plugingui/nativewindow_x11.h index c6c038e..eb88b6c 100644 --- a/plugingui/nativewindow_x11.h +++ b/plugingui/nativewindow_x11.h @@ -48,9 +48,9 @@ public: // From NativeWindow: void setFixedSize(std::size_t width, std::size_t height) override; void resize(std::size_t width, std::size_t height) override; - std::pair getSize() override; + std::pair getSize() const override; void move(int x, int y) override; - std::pair getPosition() override; + std::pair getPosition() const override; void show() override; void hide() override; bool visible() const override; -- cgit v1.2.3