summaryrefslogtreecommitdiff
path: root/dggui/nativewindow_pugl.cc
diff options
context:
space:
mode:
Diffstat (limited to 'dggui/nativewindow_pugl.cc')
-rw-r--r--dggui/nativewindow_pugl.cc382
1 files changed, 382 insertions, 0 deletions
diff --git a/dggui/nativewindow_pugl.cc b/dggui/nativewindow_pugl.cc
new file mode 100644
index 0000000..f94b82b
--- /dev/null
+++ b/dggui/nativewindow_pugl.cc
@@ -0,0 +1,382 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/***************************************************************************
+ * nativewindow_pugl.cc
+ *
+ * Fri Dec 28 18:45:57 CET 2012
+ * Copyright 2012 Bent Bisballe Nyeng
+ * deva@aasimon.org
+ ****************************************************************************/
+
+/*
+ * This file is part of DrumGizmo.
+ *
+ * DrumGizmo is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * DrumGizmo 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with DrumGizmo; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+#include "nativewindow_pugl.h"
+
+#include <stdlib.h>
+#include <list>
+
+#ifdef __APPLE__
+#include <OpenGL/glu.h>
+#else
+#include <GL/glu.h>
+#include <GL/glext.h>
+#include <GL/gl.h>
+#endif
+
+#include "window.h"
+#include "guievent.h"
+
+#include <hugin.hpp>
+
+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<std::size_t, std::size_t> 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<ResizeEvent>();
+ 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>();
+ 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>();
+ 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>();
+ 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();
+
+ 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);
+
+ 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,
+ window.wpixbuf.buf);
+
+ glEnable(GL_TEXTURE_2D);
+
+ glBegin(GL_QUADS);
+ 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();
+
+ puglLeaveContext(view, true);
+}
+
+void NativeWindowPugl::onMouse(PuglView* view, int button, bool press, int x, int y)
+{
+ NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view);
+
+ DEBUG(nativewindow_pugl, "Mouse %d %s at (%d,%d)\n", button,
+ press? "down":"up", x, y);
+
+ ButtonEvent* e = new ButtonEvent();
+ e->x = x;
+ e->y = y;
+
+ switch(button) {
+ case 1:
+ e->button = MouseButton::left;
+ break;
+ case 2:
+ e->button = MouseButton::middle;
+ break;
+ case 3:
+ default:
+ e->button = MouseButton::right;
+ break;
+ }
+
+ e->direction = press ? Direction::down : Direction::up;
+ e->doubleClick = false;
+
+ native->eventq.push_back(e);
+}
+
+void NativeWindowPugl::onKeyboard(PuglView* view, bool press, uint32_t key)
+{
+ NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view);
+
+ KeyEvent* e = new KeyEvent();
+ e->direction = press ? Direction::down : Direction::up;
+
+ switch(key)
+ {
+ case PUGL_KEY_LEFT: e->keycode = Key::left; break;
+ case PUGL_KEY_RIGHT: e->keycode = Key::right; break;
+ case PUGL_KEY_UP: e->keycode = Key::up; break;
+ case PUGL_KEY_DOWN: e->keycode = Key::down; break;
+ case PUGL_KEY_PAGE_UP: e->keycode = Key::pageDown; break;
+ case PUGL_KEY_PAGE_DOWN: e->keycode = Key::pageUp; break;
+ default: e->keycode = Key::unknown; break;
+ }
+
+ // TODO: perform character type check
+ if(e->keycode == Key::unknown)
+ {
+ e->keycode = Key::character;
+ e->text.assign(1, (char)key);
+ }
+
+ native->eventq.push_back(e);
+}
+
+} // GUI::