/* -*- 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 #include #ifdef __APPLE__ #include #else #include #include #include #endif #include "window.h" #include "guievent.h" #include namespace GUI { void NativeWindowPugl::onDisplay(PuglView* view) { NativeWindowPugl* native = (NativeWindowPugl*)puglGetHandle(view); Window& window = native->window; glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); 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_LINEAR); //GL_NEAREST = no smoothing glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 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.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); glEnd(); glDeleteTextures(1, &image); glDisable(GL_TEXTURE_2D); glFlush(); puglPostRedisplay(view); } 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; printf("%d\n", key); 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); } printf("\t text: %s\n", e->text.c_str()); 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::