Browse Source

Update DGL

tags/1.9.4
falkTX 10 years ago
parent
commit
281b0f58e9
12 changed files with 115 additions and 1947 deletions
  1. +3
    -0
      source/modules/dgl/ImageKnob.hpp
  2. +3
    -2
      source/modules/dgl/ImageSlider.hpp
  3. +0
    -2
      source/modules/dgl/Window.hpp
  4. +48
    -24
      source/modules/dgl/src/ImageKnob.cpp
  5. +45
    -36
      source/modules/dgl/src/ImageSlider.cpp
  6. +16
    -24
      source/modules/dgl/src/Window.cpp
  7. +0
    -357
      source/modules/dgl/src/pugl/copy/pugl.h
  8. +0
    -160
      source/modules/dgl/src/pugl/copy/pugl_internal.h
  9. +0
    -442
      source/modules/dgl/src/pugl/copy/pugl_osx.m
  10. +0
    -387
      source/modules/dgl/src/pugl/copy/pugl_win.cpp
  11. +0
    -397
      source/modules/dgl/src/pugl/copy/pugl_x11.c
  12. +0
    -116
      source/modules/dgl/src/pugl/pugl_osx.diff

+ 3
- 0
source/modules/dgl/ImageKnob.hpp View File

@@ -49,6 +49,7 @@ public:


void setOrientation(Orientation orientation); void setOrientation(Orientation orientation);
void setRange(float min, float max); void setRange(float min, float max);
void setStep(float step);
void setValue(float value, bool sendCallback = false); void setValue(float value, bool sendCallback = false);
void setRotationAngle(int angle); void setRotationAngle(int angle);


@@ -65,7 +66,9 @@ private:
Image fImage; Image fImage;
float fMinimum; float fMinimum;
float fMaximum; float fMaximum;
float fStep;
float fValue; float fValue;
float fValueTmp;
Orientation fOrientation; Orientation fOrientation;


int fRotationAngle; int fRotationAngle;


+ 3
- 2
source/modules/dgl/ImageSlider.hpp View File

@@ -48,8 +48,8 @@ public:
void setEndPos(int x, int y); void setEndPos(int x, int y);


void setRange(float min, float max); void setRange(float min, float max);
void setStep(float step);
void setValue(float value, bool sendCallback = false); void setValue(float value, bool sendCallback = false);
void setIsSwitch(bool yesNo);


void setCallback(Callback* callback); void setCallback(Callback* callback);


@@ -62,9 +62,10 @@ private:
Image fImage; Image fImage;
float fMinimum; float fMinimum;
float fMaximum; float fMaximum;
float fStep;
float fValue; float fValue;
float fValueTmp;


bool fIsSwitch;
bool fDragging; bool fDragging;
int fStartedX; int fStartedX;
int fStartedY; int fStartedY;


+ 0
- 2
source/modules/dgl/Window.hpp View File

@@ -40,8 +40,6 @@ public:
Window(App& app, intptr_t parentId); Window(App& app, intptr_t parentId);
virtual ~Window(); virtual ~Window();


void setTransient(const intptr_t win);

void show(); void show();
void hide(); void hide();
void close(); void close();


+ 48
- 24
source/modules/dgl/src/ImageKnob.cpp View File

@@ -16,7 +16,7 @@


#include "../ImageKnob.hpp" #include "../ImageKnob.hpp"


#include <cassert>
#include <cmath>
#include <cstdio> #include <cstdio>


START_NAMESPACE_DGL START_NAMESPACE_DGL
@@ -28,7 +28,9 @@ ImageKnob::ImageKnob(Window& parent, const Image& image, Orientation orientation
fImage(image), fImage(image),
fMinimum(0.0f), fMinimum(0.0f),
fMaximum(1.0f), fMaximum(1.0f),
fStep(0.0f),
fValue(0.5f), fValue(0.5f),
fValueTmp(fValue),
fOrientation(orientation), fOrientation(orientation),
fRotationAngle(0), fRotationAngle(0),
fDragging(false), fDragging(false),
@@ -49,7 +51,9 @@ ImageKnob::ImageKnob(Widget* widget, const Image& image, Orientation orientation
fImage(image), fImage(image),
fMinimum(0.0f), fMinimum(0.0f),
fMaximum(1.0f), fMaximum(1.0f),
fStep(0.0f),
fValue(0.5f), fValue(0.5f),
fValueTmp(fValue),
fOrientation(orientation), fOrientation(orientation),
fRotationAngle(0), fRotationAngle(0),
fDragging(false), fDragging(false),
@@ -70,7 +74,9 @@ ImageKnob::ImageKnob(const ImageKnob& imageKnob)
fImage(imageKnob.fImage), fImage(imageKnob.fImage),
fMinimum(imageKnob.fMinimum), fMinimum(imageKnob.fMinimum),
fMaximum(imageKnob.fMaximum), fMaximum(imageKnob.fMaximum),
fStep(imageKnob.fStep),
fValue(imageKnob.fValue), fValue(imageKnob.fValue),
fValueTmp(fValue),
fOrientation(imageKnob.fOrientation), fOrientation(imageKnob.fOrientation),
fRotationAngle(imageKnob.fRotationAngle), fRotationAngle(imageKnob.fRotationAngle),
fDragging(false), fDragging(false),
@@ -129,12 +135,21 @@ void ImageKnob::setRange(float min, float max)
fMaximum = max; fMaximum = max;
} }


void ImageKnob::setStep(float step)
{
fStep = step;
}

void ImageKnob::setValue(float value, bool sendCallback) void ImageKnob::setValue(float value, bool sendCallback)
{ {
if (fValue == value) if (fValue == value)
return; return;


fValue = value; fValue = value;

if (fStep == 0.0f)
fValueTmp = value;

repaint(); repaint();


if (sendCallback && fCallback != nullptr) if (sendCallback && fCallback != nullptr)
@@ -280,40 +295,49 @@ bool ImageKnob::onMotion(int x, int y)
if (! fDragging) if (! fDragging)
return false; return false;


bool doVal = false;
float d, value;

if (fOrientation == ImageKnob::Horizontal) if (fOrientation == ImageKnob::Horizontal)
{ {
int movX = x - fLastX;

if (movX != 0)
if (int movX = x - fLastX)
{ {
float d = (getModifiers() & MODIFIER_SHIFT) ? 2000.0f : 200.0f;
float value = fValue + (float(fMaximum - fMinimum) / d * float(movX));

if (value < fMinimum)
value = fMinimum;
else if (value > fMaximum)
value = fMaximum;

setValue(value, true);
d = (getModifiers() & MODIFIER_SHIFT) ? 2000.0f : 200.0f;
value = fValueTmp + (float(fMaximum - fMinimum) / d * float(movX));
doVal = true;
} }
} }
else if (fOrientation == ImageKnob::Vertical) else if (fOrientation == ImageKnob::Vertical)
{ {
int movY = fLastY - y;

if (movY != 0)
if (int movY = fLastY - y)
{ {
float d = (getModifiers() & MODIFIER_SHIFT) ? 2000.0f : 200.0f;
float value = fValue + (float(fMaximum - fMinimum) / d * float(movY));
d = (getModifiers() & MODIFIER_SHIFT) ? 2000.0f : 200.0f;
value = fValueTmp + (float(fMaximum - fMinimum) / d * float(movY));
doVal = true;
}
}


if (value < fMinimum)
value = fMinimum;
else if (value > fMaximum)
value = fMaximum;
if (! doVal)
return false;


setValue(value, true);
}
if (value < fMinimum)
{
value = fMinimum;
fValueTmp = value;
} }
else if (value > fMaximum)
{
value = fMaximum;
fValueTmp = value;
}
else if (fStep != 0.0f)
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f);
}

setValue(value, true);


fLastX = x; fLastX = x;
fLastY = y; fLastY = y;


+ 45
- 36
source/modules/dgl/src/ImageSlider.cpp View File

@@ -16,6 +16,8 @@


#include "../ImageSlider.hpp" #include "../ImageSlider.hpp"


#include <cmath>

START_NAMESPACE_DGL START_NAMESPACE_DGL


// ----------------------------------------------------------------------- // -----------------------------------------------------------------------
@@ -25,8 +27,9 @@ ImageSlider::ImageSlider(Window& parent, const Image& image)
fImage(image), fImage(image),
fMinimum(0.0f), fMinimum(0.0f),
fMaximum(1.0f), fMaximum(1.0f),
fStep(0.0f),
fValue(0.5f), fValue(0.5f),
fIsSwitch(false),
fValueTmp(fValue),
fDragging(false), fDragging(false),
fStartedX(0), fStartedX(0),
fStartedY(0), fStartedY(0),
@@ -40,8 +43,9 @@ ImageSlider::ImageSlider(Widget* widget, const Image& image)
fImage(image), fImage(image),
fMinimum(0.0f), fMinimum(0.0f),
fMaximum(1.0f), fMaximum(1.0f),
fStep(0.0f),
fValue(0.5f), fValue(0.5f),
fIsSwitch(false),
fValueTmp(fValue),
fDragging(false), fDragging(false),
fStartedX(0), fStartedX(0),
fStartedY(0), fStartedY(0),
@@ -55,8 +59,9 @@ ImageSlider::ImageSlider(const ImageSlider& imageSlider)
fImage(imageSlider.fImage), fImage(imageSlider.fImage),
fMinimum(imageSlider.fMinimum), fMinimum(imageSlider.fMinimum),
fMaximum(imageSlider.fMaximum), fMaximum(imageSlider.fMaximum),
fStep(imageSlider.fStep),
fValue(imageSlider.fValue), fValue(imageSlider.fValue),
fIsSwitch(imageSlider.fIsSwitch),
fValueTmp(fValue),
fDragging(false), fDragging(false),
fStartedX(0), fStartedX(0),
fStartedY(0), fStartedY(0),
@@ -118,27 +123,27 @@ void ImageSlider::setRange(float min, float max)
fMaximum = max; fMaximum = max;
} }


void ImageSlider::setStep(float step)
{
fStep = step;
}

void ImageSlider::setValue(float value, bool sendCallback) void ImageSlider::setValue(float value, bool sendCallback)
{ {
if (fValue == value) if (fValue == value)
return; return;


fValue = value; fValue = value;

if (fStep == 0.0f)
fValueTmp = value;

repaint(); repaint();


if (sendCallback && fCallback != nullptr) if (sendCallback && fCallback != nullptr)
fCallback->imageSliderValueChanged(this, fValue); fCallback->imageSliderValueChanged(this, fValue);
} }


void ImageSlider::setIsSwitch(bool yesNo)
{
if (fIsSwitch == yesNo)
return;

fIsSwitch = yesNo;
repaint();
}

void ImageSlider::setCallback(Callback* callback) void ImageSlider::setCallback(Callback* callback)
{ {
fCallback = callback; fCallback = callback;
@@ -198,21 +203,23 @@ bool ImageSlider::onMouse(int button, bool press, int x, int y)


float value; float value;


if (fIsSwitch)
value = fMaximum - vper * (fMaximum - fMinimum);

if (value < fMinimum)
{ {
if (vper < 0.5f)
value = fMaximum;
else
value = fMinimum;
value = fMinimum;
fValueTmp = value;
} }
else
else if (value > fMaximum)
{ {
value = fMaximum - vper * (fMaximum - fMinimum);

if (value < fMinimum)
value = fMinimum;
else if (value > fMaximum)
value = fMaximum;
value = fMaximum;
fValueTmp = value;
}
else if (fStep != 0.0f)
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f);
} }


fDragging = true; fDragging = true;
@@ -262,21 +269,23 @@ bool ImageSlider::onMotion(int x, int y)


float value; float value;


if (fIsSwitch)
value = fMaximum - vper * (fMaximum - fMinimum);

if (value < fMinimum)
{ {
if (vper < 0.5f)
value = fMaximum;
else
value = fMinimum;
value = fMinimum;
fValueTmp = value;
} }
else
else if (value > fMaximum)
{ {
value = fMaximum - vper * (fMaximum - fMinimum);

if (value < fMinimum)
value = fMinimum;
else if (value > fMaximum)
value = fMaximum;
value = fMaximum;
fValueTmp = value;
}
else if (fStep != 0.0f)
{
fValueTmp = value;
const float rest = std::fmod(value, fStep);
value = value - rest + (rest > fStep/2.0f ? fStep : 0.0f);
} }


setValue(value, true); setValue(value, true);


+ 16
- 24
source/modules/dgl/src/Window.cpp View File

@@ -119,11 +119,11 @@ public:
PrivateData(App& app, Window* const self, const intptr_t parentId) PrivateData(App& app, Window* const self, const intptr_t parentId)
: fApp(app), : fApp(app),
fSelf(self), fSelf(self),
fView(puglCreate(parentId, "Window", 100, 100, true, true)),
fView(puglCreate(parentId, "Window", 100, 100, (parentId == 0), (parentId != 0))),
fFirstInit(true), fFirstInit(true),
fVisible(true),
fResizable(false),
fUsingEmbed(true),
fVisible(parentId != 0),
fResizable(parentId == 0),
fUsingEmbed(parentId != 0),
#if DGL_OS_WINDOWS #if DGL_OS_WINDOWS
hwnd(0) hwnd(0)
#elif DGL_OS_LINUX #elif DGL_OS_LINUX
@@ -133,12 +133,20 @@ public:
_dummy('\0') _dummy('\0')
#endif #endif
{ {
DBG("Creating embedded window..."); DBGF;
if (parentId != 0) {
DBG("Creating embedded window..."); DBGF;
} else {
DBG("Creating window without parent..."); DBGF;
}

init(); init();


DBG("NOTE: Embed window is always visible and non-resizable\n");
fApp._oneShown();
fFirstInit = false;
if (parentId != 0)
{
DBG("NOTE: Embed window is always visible and non-resizable\n");
fApp._oneShown();
fFirstInit = false;
}
} }


void init() void init()
@@ -210,17 +218,6 @@ public:
DBG("Success!\n"); DBG("Success!\n");
} }


// TESTING
void setTransient(const intptr_t win)
{
#if DGL_OS_LINUX
XSetTransientForHint(xDisplay, xWindow, (::Window)win);
XFlush(xDisplay);
#else
return; (void)win;
#endif
}

// ------------------------------------------------------------------- // -------------------------------------------------------------------


void close() void close()
@@ -791,11 +788,6 @@ Window::~Window()
delete pData; delete pData;
} }


void Window::setTransient(const intptr_t win)
{
pData->setTransient(win);
}

void Window::show() void Window::show()
{ {
pData->setVisible(true); pData->setVisible(true);


+ 0
- 357
source/modules/dgl/src/pugl/copy/pugl.h View File

@@ -1,357 +0,0 @@
/*
Copyright 2012 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file pugl.h API for Pugl, a minimal portable API for OpenGL.
*/

#ifndef PUGL_H_INCLUDED
#define PUGL_H_INCLUDED

#include <stdint.h>

/*
This API is pure portable C and contains no platform specific elements, or
even a GL dependency. However, unfortunately GL includes vary across
platforms so they are included here to allow for pure portable programs.
*/
#ifdef __APPLE__
# include "OpenGL/gl.h"
#else
# ifdef _WIN32
# include <windows.h> /* Broken Windows GL headers require this */
# endif
# include "GL/gl.h"
#endif

#ifdef PUGL_SHARED
# ifdef _WIN32
# define PUGL_LIB_IMPORT __declspec(dllimport)
# define PUGL_LIB_EXPORT __declspec(dllexport)
# else
# define PUGL_LIB_IMPORT __attribute__((visibility("default")))
# define PUGL_LIB_EXPORT __attribute__((visibility("default")))
# endif
# ifdef PUGL_INTERNAL
# define PUGL_API PUGL_LIB_EXPORT
# else
# define PUGL_API PUGL_LIB_IMPORT
# endif
#else
# define PUGL_API
#endif

#ifdef __cplusplus
extern "C" {
#else
# include <stdbool.h>
#endif

/**
@defgroup pugl Pugl
A minimal portable API for OpenGL.
@{
*/

/**
An OpenGL view.
*/
typedef struct PuglViewImpl PuglView;

/**
A native window handle.

On X11, this is a Window.
On OSX, this is an NSView*.
On Windows, this is a HWND.
*/
typedef intptr_t PuglNativeWindow;

/**
Return status code.
*/
typedef enum {
PUGL_SUCCESS = 0
} PuglStatus;

/**
Convenience symbols for ASCII control characters.
*/
typedef enum {
PUGL_CHAR_BACKSPACE = 0x08,
PUGL_CHAR_ESCAPE = 0x1B,
PUGL_CHAR_DELETE = 0x7F
} PuglChar;

/**
Special (non-Unicode) keyboard keys.
*/
typedef enum {
PUGL_KEY_F1 = 1,
PUGL_KEY_F2,
PUGL_KEY_F3,
PUGL_KEY_F4,
PUGL_KEY_F5,
PUGL_KEY_F6,
PUGL_KEY_F7,
PUGL_KEY_F8,
PUGL_KEY_F9,
PUGL_KEY_F10,
PUGL_KEY_F11,
PUGL_KEY_F12,
PUGL_KEY_LEFT,
PUGL_KEY_UP,
PUGL_KEY_RIGHT,
PUGL_KEY_DOWN,
PUGL_KEY_PAGE_UP,
PUGL_KEY_PAGE_DOWN,
PUGL_KEY_HOME,
PUGL_KEY_END,
PUGL_KEY_INSERT,
PUGL_KEY_SHIFT,
PUGL_KEY_CTRL,
PUGL_KEY_ALT,
PUGL_KEY_SUPER
} PuglKey;

/**
Keyboard modifier flags.
*/
typedef enum {
PUGL_MOD_SHIFT = 1, /**< Shift key */
PUGL_MOD_CTRL = 1 << 1, /**< Control key */
PUGL_MOD_ALT = 1 << 2, /**< Alt/Option key */
PUGL_MOD_SUPER = 1 << 3 /**< Mod4/Command/Windows key */
} PuglMod;

/**
Handle for opaque user data.
*/
typedef void* PuglHandle;

/**
A function called when the window is closed.
*/
typedef void (*PuglCloseFunc)(PuglView* view);

/**
A function called to draw the view contents with OpenGL.
*/
typedef void (*PuglDisplayFunc)(PuglView* view);

/**
A function called when a key is pressed or released.
@param view The view the event occured in.
@param press True if the key was pressed, false if released.
@param key Unicode point of the key pressed.
*/
typedef void (*PuglKeyboardFunc)(PuglView* view, bool press, uint32_t key);

/**
A function called when the pointer moves.
@param view The view the event occured in.
@param x The window-relative x coordinate of the pointer.
@param y The window-relative y coordinate of the pointer.
*/
typedef void (*PuglMotionFunc)(PuglView* view, int x, int y);

/**
A function called when a mouse button is pressed or released.
@param view The view the event occured in.
@param button The button number (1 = left, 2 = middle, 3 = right).
@param press True if the key was pressed, false if released.
@param x The window-relative x coordinate of the pointer.
@param y The window-relative y coordinate of the pointer.
*/
typedef void (*PuglMouseFunc)(
PuglView* view, int button, bool press, int x, int y);

/**
A function called when the view is resized.
@param view The view being resized.
@param width The new view width.
@param height The new view height.
*/
typedef void (*PuglReshapeFunc)(PuglView* view, int width, int height);

/**
A function called on scrolling (e.g. mouse wheel or track pad).

The distances used here are in "lines", a single tick of a clicking mouse
wheel. For example, @p dy = 1.0 scrolls 1 line up. Some systems and
devices support finer resolution and/or higher values for fast scrolls,
so programs should handle any value gracefully.

@param view The view being scrolled.
@param dx The scroll x distance.
@param dx The scroll y distance.
*/
typedef void (*PuglScrollFunc)(PuglView* view,
int x,
int y,
float dx,
float dy);

/**
A function called when a special key is pressed or released.

This callback allows the use of keys that do not have unicode points.

@param view The view the event occured in.
@param press True if the key was pressed, false if released.
@param key The key pressed.
*/
typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key);

/**
Create a new GL window.
@param parent Parent window, or 0 for top level.
@param title Window title, or NULL.
@param width Window width in pixels.
@param height Window height in pixels.
@param resizable Whether window should be user resizable.
@param visible Whether window should be initially visible.
*/
PUGL_API PuglView*
puglCreate(PuglNativeWindow parent,
const char* title,
int width,
int height,
bool resizable,
bool visible);

/**
Set the handle to be passed to all callbacks.

This is generally a pointer to a struct which contains all necessary state.
Everything needed in callbacks should be here, not in static variables.

Note the lack of this facility makes GLUT unsuitable for plugins or
non-trivial programs; this mistake is largely why Pugl exists.
*/
PUGL_API void
puglSetHandle(PuglView* view, PuglHandle handle);

/**
Get the handle to be passed to all callbacks.
*/
PUGL_API PuglHandle
puglGetHandle(PuglView* view);

/**
Return the timestamp (if any) of the currently-processing event.
*/
PUGL_API uint32_t
puglGetEventTimestamp(PuglView* view);

/**
Get the currently active modifiers (PuglMod flags).

This should only be called from an event handler.
*/
PUGL_API int
puglGetModifiers(PuglView* view);

/**
Ignore synthetic repeated key events.
*/
PUGL_API void
puglIgnoreKeyRepeat(PuglView* view, bool ignore);

/**
Set the function to call when the window is closed.
*/
PUGL_API void
puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc);

/**
Set the display function which should draw the UI using GL.
*/
PUGL_API void
puglSetDisplayFunc(PuglView* view, PuglDisplayFunc displayFunc);

/**
Set the function to call on keyboard events.
*/
PUGL_API void
puglSetKeyboardFunc(PuglView* view, PuglKeyboardFunc keyboardFunc);

/**
Set the function to call on mouse motion.
*/
PUGL_API void
puglSetMotionFunc(PuglView* view, PuglMotionFunc motionFunc);

/**
Set the function to call on mouse button events.
*/
PUGL_API void
puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc);

/**
Set the function to call on scroll events.
*/
PUGL_API void
puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc);

/**
Set the function to call on special events.
*/
PUGL_API void
puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc);

/**
Set the function to call when the window size changes.
*/
PUGL_API void
puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);

/**
Return the native window handle.
*/
PUGL_API PuglNativeWindow
puglGetNativeWindow(PuglView* view);

/**
Process all pending window events.

This handles input events as well as rendering, so it should be called
regularly and rapidly enough to keep the UI responsive.
*/
PUGL_API PuglStatus
puglProcessEvents(PuglView* view);

/**
Request a redisplay on the next call to puglProcessEvents().
*/
PUGL_API void
puglPostRedisplay(PuglView* view);

/**
Destroy a GL window.
*/
PUGL_API void
puglDestroy(PuglView* view);

/**
@}
*/

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* PUGL_H_INCLUDED */

+ 0
- 160
source/modules/dgl/src/pugl/copy/pugl_internal.h View File

@@ -1,160 +0,0 @@
/*
Copyright 2012 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file pugl_internal.h Private platform-independent definitions.

Note this file contains function definitions, so it must be compiled into
the final binary exactly once. Each platform specific implementation file
including it once should achieve this.

If you are copying the pugl code into your source tree, the following
symbols can be defined to tweak pugl behaviour:

PUGL_GRAB_FOCUS: Work around reparent keyboard issues by grabbing focus.
PUGL_VERBOSE: Print GL information to console.
*/

#include "pugl.h"

#ifdef PUGL_VERBOSE
# include <stdio.h>
# define PUGL_LOG(str) fprintf(stderr, "pugl: " str)
# define PUGL_LOGF(fmt, ...) fprintf(stderr, "pugl: " fmt, __VA_ARGS__)
#else
# define PUGL_LOG(str)
# define PUGL_LOGF(fmt, ...)
#endif

void puglDefaultReshape(PuglView* view, int width, int height);

typedef struct PuglInternalsImpl PuglInternals;

struct PuglViewImpl {
PuglHandle handle;
PuglCloseFunc closeFunc;
PuglDisplayFunc displayFunc;
PuglKeyboardFunc keyboardFunc;
PuglMotionFunc motionFunc;
PuglMouseFunc mouseFunc;
PuglReshapeFunc reshapeFunc;
PuglScrollFunc scrollFunc;
PuglSpecialFunc specialFunc;

PuglInternals* impl;

int width;
int height;
int mods;
bool mouse_in_view;
bool ignoreKeyRepeat;
bool redisplay;
uint32_t event_timestamp_ms;
};

void
puglSetHandle(PuglView* view, PuglHandle handle)
{
view->handle = handle;
}

PuglHandle
puglGetHandle(PuglView* view)
{
return view->handle;
}

uint32_t
puglGetEventTimestamp(PuglView* view)
{
return view->event_timestamp_ms;
}

int
puglGetModifiers(PuglView* view)
{
return view->mods;
}

void
puglDefaultReshape(PuglView* view, int width, int height)
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, width, height, 0, 0, 1);
glViewport(0, 0, width, height);

glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
return;

// unused
(void)view;
}

void
puglIgnoreKeyRepeat(PuglView* view, bool ignore)
{
view->ignoreKeyRepeat = ignore;
}

void
puglSetCloseFunc(PuglView* view, PuglCloseFunc closeFunc)
{
view->closeFunc = closeFunc;
}

void
puglSetDisplayFunc(PuglView* view, PuglDisplayFunc displayFunc)
{
view->displayFunc = displayFunc;
}

void
puglSetKeyboardFunc(PuglView* view, PuglKeyboardFunc keyboardFunc)
{
view->keyboardFunc = keyboardFunc;
}

void
puglSetMotionFunc(PuglView* view, PuglMotionFunc motionFunc)
{
view->motionFunc = motionFunc;
}

void
puglSetMouseFunc(PuglView* view, PuglMouseFunc mouseFunc)
{
view->mouseFunc = mouseFunc;
}

void
puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc)
{
view->reshapeFunc = reshapeFunc;
}

void
puglSetScrollFunc(PuglView* view, PuglScrollFunc scrollFunc)
{
view->scrollFunc = scrollFunc;
}

void
puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc)
{
view->specialFunc = specialFunc;
}

+ 0
- 442
source/modules/dgl/src/pugl/copy/pugl_osx.m View File

@@ -1,442 +0,0 @@
/*
Copyright 2012 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file pugl_osx.m OSX/Cocoa Pugl Implementation.
*/

#include <stdlib.h>

#import <Cocoa/Cocoa.h>

#include "pugl_internal.h"

@interface PuglWindow : NSWindow
{
@public
PuglView* puglview;
}

- (id) initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag;
- (void) setPuglview:(PuglView*)view;
- (BOOL) windowShouldClose:(id)sender;
- (BOOL) canBecomeKeyWindow:(id)sender;
@end

@implementation PuglWindow

- (id)initWithContentRect:(NSRect)contentRect
styleMask:(unsigned int)aStyle
backing:(NSBackingStoreType)bufferingType
defer:(BOOL)flag
{
NSWindow* result = [super initWithContentRect:contentRect
styleMask:(NSClosableWindowMask |
NSTitledWindowMask |
NSResizableWindowMask)
backing:NSBackingStoreBuffered defer:NO];

[result setAcceptsMouseMovedEvents:YES];
[result setLevel: CGShieldingWindowLevel() + 1];

return result;
}

- (void)setPuglview:(PuglView*)view
{
puglview = view;
[self setContentSize:NSMakeSize(view->width, view->height) ];
}

- (BOOL)windowShouldClose:(id)sender
{
if (puglview->closeFunc)
puglview->closeFunc(puglview);
return YES;
}

- (BOOL) canBecomeKeyWindow:(id)sender
{
return NO;
}

@end

void
puglDisplay(PuglView* view)
{
if (view->displayFunc) {
view->displayFunc(view);
}
}

@interface PuglOpenGLView : NSOpenGLView
{
int colorBits;
int depthBits;
@public
PuglView* puglview;

NSTrackingArea* trackingArea;
}

- (id) initWithFrame:(NSRect)frame
colorBits:(int)numColorBits
depthBits:(int)numDepthBits;
- (void) reshape;
- (void) drawRect:(NSRect)rect;
- (void) mouseMoved:(NSEvent*)event;
- (void) mouseDragged:(NSEvent*)event;
- (void) mouseDown:(NSEvent*)event;
- (void) mouseUp:(NSEvent*)event;
- (void) rightMouseDragged:(NSEvent*)event;
- (void) rightMouseDown:(NSEvent*)event;
- (void) rightMouseUp:(NSEvent*)event;
- (void) keyDown:(NSEvent*)event;
- (void) keyUp:(NSEvent*)event;
- (void) flagsChanged:(NSEvent*)event;

@end

@implementation PuglOpenGLView

- (id) initWithFrame:(NSRect)frame
colorBits:(int)numColorBits
depthBits:(int)numDepthBits
{
colorBits = numColorBits;
depthBits = numDepthBits;

NSOpenGLPixelFormatAttribute pixelAttribs[16] = {
NSOpenGLPFADoubleBuffer,
NSOpenGLPFAAccelerated,
NSOpenGLPFAColorSize,
colorBits,
NSOpenGLPFADepthSize,
depthBits,
0
};

NSOpenGLPixelFormat* pixelFormat = [[NSOpenGLPixelFormat alloc]
initWithAttributes:pixelAttribs];

if (pixelFormat) {
self = [super initWithFrame:frame pixelFormat:pixelFormat];
[pixelFormat release];
if (self) {
[[self openGLContext] makeCurrentContext];
[self reshape];
}
} else {
self = nil;
}

return self;
}

- (void) reshape
{
[[self openGLContext] update];

NSRect bounds = [self bounds];
int width = bounds.size.width;
int height = bounds.size.height;

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.
*/
if (puglview->reshapeFunc) {
puglview->reshapeFunc(puglview, width, height);
} else {
puglDefaultReshape(puglview, width, height);
}

puglview->width = width;
puglview->height = height;
}
}

- (void) drawRect:(NSRect)rect
{
puglDisplay(puglview);
glFlush();
glSwapAPPLE();
}

static unsigned
getModifiers(PuglView* view, NSEvent* ev)
{
const unsigned modifierFlags = [ev modifierFlags];

view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);

double ts = [ev timestamp] * 1000.0;
ts = (uint32)ts % 500000; //ridiculously large vals won't fit
view->event_timestamp_ms = ts;

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)updateTrackingAreas
{
if (trackingArea != nil) {
[self removeTrackingArea:trackingArea];
[trackingArea release];
}

const int opts = (NSTrackingMouseEnteredAndExited |
NSTrackingMouseMoved |
NSTrackingActiveAlways);
trackingArea = [ [NSTrackingArea alloc] initWithRect:[self bounds]
options:opts
owner:self
userInfo:nil];
[self addTrackingArea:trackingArea];
}

- (void)mouseEntered:(NSEvent*)theEvent
{
[self updateTrackingAreas];
}

- (void)mouseExited:(NSEvent*)theEvent
{
}

- (void) mouseMoved:(NSEvent*)event
{
if (puglview->motionFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
}
}

- (void) mouseDragged:(NSEvent*)event
{
if (puglview->motionFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
}
}

- (void) rightMouseDragged:(NSEvent*)event
{
if (puglview->motionFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->motionFunc(puglview, loc.x, puglview->height - loc.y);
}
}

- (void) mouseDown:(NSEvent*)event
{
if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->mouseFunc(puglview, 1, true, loc.x, puglview->height - loc.y);
}
}

- (void) mouseUp:(NSEvent*)event
{
if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->mouseFunc(puglview, 1, false, loc.x, puglview->height - loc.y);
}
[self updateTrackingAreas];
}

- (void) rightMouseDown:(NSEvent*)event
{
if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->mouseFunc(puglview, 3, true, loc.x, puglview->height - loc.y);
}
}

- (void) rightMouseUp:(NSEvent*)event
{
if (puglview->mouseFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->mouseFunc(puglview, 3, false, loc.x, puglview->height - loc.y);
}
}

- (void) scrollWheel:(NSEvent*)event
{
if (puglview->scrollFunc) {
NSPoint loc = [event locationInWindow];
puglview->mods = getModifiers(puglview, event);
puglview->scrollFunc(puglview,
loc.x, puglview->height - loc.y,
[event deltaX], [event deltaY]);
}
[self updateTrackingAreas];
}

- (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

struct PuglInternalsImpl {
PuglOpenGLView* glview;
id window;
};

PuglView*
puglCreate(PuglNativeWindow parent,
const char* title,
int width,
int height,
bool resizable,
bool visible)
{
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
if (!view || !impl) {
return NULL;
}

view->impl = impl;
view->width = width;
view->height = height;

[NSAutoreleasePool new];
[NSApplication sharedApplication];

NSString* titleString = [[NSString alloc]
initWithBytes:title
length:strlen(title)
encoding:NSUTF8StringEncoding];

id window = [[PuglWindow new]retain];

[window setPuglview:view];
[window setTitle:titleString];

impl->glview = [PuglOpenGLView new];
impl->window = window;
impl->glview->puglview = view;

[window setContentView:impl->glview];
[NSApp activateIgnoringOtherApps:YES];
[window makeFirstResponder:impl->glview];

[window makeKeyAndOrderFront:window];

if (! visible) {
[window setIsVisible:NO];
}

return view;
}

void
puglDestroy(PuglView* view)
{
view->impl->glview->puglview = NULL;
[view->impl->window close];
[view->impl->glview release];
[view->impl->window release];
free(view->impl);
free(view);
}

PuglStatus
puglProcessEvents(PuglView* view)
{
[view->impl->glview setNeedsDisplay: YES];

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSEvent* event;

for (;;) {
event = [view->impl->window
nextEventMatchingMask:NSAnyEventMask
untilDate:[NSDate distantPast]
inMode:NSDefaultRunLoopMode
dequeue:YES];

if (event == nil)
break;

[view->impl->window sendEvent: event];
}
[pool release];

return PUGL_SUCCESS;
}

void
puglPostRedisplay(PuglView* view)
{
view->redisplay = true;
}

PuglNativeWindow
puglGetNativeWindow(PuglView* view)
{
return (PuglNativeWindow)view->impl->glview;
}

+ 0
- 387
source/modules/dgl/src/pugl/copy/pugl_win.cpp View File

@@ -1,387 +0,0 @@
/*
Copyright 2012 David Robillard <http://drobilla.net>

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file pugl_win.cpp Windows/WGL Pugl Implementation.
*/

#include <windows.h>
#include <windowsx.h>
#include <GL/gl.h>

#include <stdio.h>
#include <stdlib.h>

#include "pugl_internal.h"

#ifndef WM_MOUSEWHEEL
# define WM_MOUSEWHEEL 0x020A
#endif
#ifndef WM_MOUSEHWHEEL
# define WM_MOUSEHWHEEL 0x020E
#endif
#ifndef WHEEL_DELTA
# define WHEEL_DELTA 120
#endif

const int LOCAL_CLOSE_MSG = WM_USER + 50;

struct PuglInternalsImpl {
HWND hwnd;
HDC hdc;
HGLRC hglrc;
WNDCLASS wc;
};

LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

PuglView*
puglCreate(PuglNativeWindow parent,
const char* title,
int width,
int height,
bool resizable,
bool visible)
{
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
if (!view || !impl) {
return NULL;
}

view->impl = impl;
view->width = width;
view->height = height;

// FIXME: This is nasty, and pugl should not have static anything.
// Should class be a parameter? Does this make sense on other platforms?
static int wc_count = 0;
char classNameBuf[256];
_snprintf(classNameBuf, sizeof(classNameBuf), "%s_%d\n", title, wc_count++);

impl->wc.style = CS_OWNDC;
impl->wc.lpfnWndProc = wndProc;
impl->wc.cbClsExtra = 0;
impl->wc.cbWndExtra = 0;
impl->wc.hInstance = 0;
impl->wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
impl->wc.hCursor = LoadCursor(NULL, IDC_ARROW);
impl->wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
impl->wc.lpszMenuName = NULL;
impl->wc.lpszClassName = classNameBuf;
RegisterClass(&impl->wc);

int winFlags = WS_POPUPWINDOW | WS_CAPTION;
if (resizable) {
winFlags |= WS_SIZEBOX;
}

// Adjust the overall window size to accomodate our requested client size
RECT wr = { 0, 0, width, height };
AdjustWindowRectEx(&wr, winFlags, FALSE, WS_EX_TOPMOST);

impl->hwnd = CreateWindowEx(
WS_EX_TOPMOST,
classNameBuf, title,
(visible ? WS_VISIBLE : 0) | (parent ? WS_CHILD : winFlags),
0, 0, wr.right-wr.left, wr.bottom-wr.top,
(HWND)parent, NULL, NULL, NULL);

if (!impl->hwnd) {
free(impl);
free(view);
return NULL;
}

#ifdef _WIN64
SetWindowLongPtr(impl->hwnd, GWLP_USERDATA, (LONG_PTR)view);
#else
SetWindowLongPtr(impl->hwnd, GWL_USERDATA, (LONG)view);
#endif

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);
wglMakeCurrent(impl->hdc, impl->hglrc);

view->width = width;
view->height = height;

return 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(view->impl);
free(view);
}

void
puglReshape(PuglView* view, int width, int height)
{
wglMakeCurrent(view->impl->hdc, view->impl->hglrc);

if (view->reshapeFunc) {
view->reshapeFunc(view, width, height);
} else {
puglDefaultReshape(view, width, height);
}

view->width = width;
view->height = height;
}

void
puglDisplay(PuglView* view)
{
wglMakeCurrent(view->impl->hdc, view->impl->hglrc);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

if (view->displayFunc) {
view->displayFunc(view);
}

glFlush();
SwapBuffers(view->impl->hdc);
view->redisplay = false;
}

static PuglKey
keySymToSpecial(int sym)
{
switch (sym) {
case VK_F1: return PUGL_KEY_F1;
case VK_F2: return PUGL_KEY_F2;
case VK_F3: return PUGL_KEY_F3;
case VK_F4: return PUGL_KEY_F4;
case VK_F5: return PUGL_KEY_F5;
case VK_F6: return PUGL_KEY_F6;
case VK_F7: return PUGL_KEY_F7;
case VK_F8: return PUGL_KEY_F8;
case VK_F9: return PUGL_KEY_F9;
case VK_F10: return PUGL_KEY_F10;
case VK_F11: return PUGL_KEY_F11;
case VK_F12: return PUGL_KEY_F12;
case VK_LEFT: return PUGL_KEY_LEFT;
case VK_UP: return PUGL_KEY_UP;
case VK_RIGHT: return PUGL_KEY_RIGHT;
case VK_DOWN: return PUGL_KEY_DOWN;
case VK_PRIOR: return PUGL_KEY_PAGE_UP;
case VK_NEXT: return PUGL_KEY_PAGE_DOWN;
case VK_HOME: return PUGL_KEY_HOME;
case VK_END: return PUGL_KEY_END;
case VK_INSERT: return PUGL_KEY_INSERT;
case VK_SHIFT: return PUGL_KEY_SHIFT;
case VK_CONTROL: return PUGL_KEY_CTRL;
case VK_MENU: return PUGL_KEY_ALT;
case VK_LWIN: return PUGL_KEY_SUPER;
case VK_RWIN: return PUGL_KEY_SUPER;
}
return (PuglKey)0;
}

static void
processMouseEvent(PuglView* view, int button, bool press, LPARAM lParam)
{
view->event_timestamp_ms = GetMessageTime();
if (press) {
SetCapture(view->impl->hwnd);
} else {
ReleaseCapture();
}
if (view->mouseFunc) {
view->mouseFunc(view, button, press,
GET_X_LPARAM(lParam),
GET_Y_LPARAM(lParam));
}
}

static void
setModifiers(PuglView* view)
{
view->mods = 0;
view->mods |= (GetKeyState(VK_SHIFT) < 0) ? PUGL_MOD_SHIFT : 0;
view->mods |= (GetKeyState(VK_CONTROL) < 0) ? PUGL_MOD_CTRL : 0;
view->mods |= (GetKeyState(VK_MENU) < 0) ? PUGL_MOD_ALT : 0;
view->mods |= (GetKeyState(VK_LWIN) < 0) ? PUGL_MOD_SUPER : 0;
view->mods |= (GetKeyState(VK_RWIN) < 0) ? PUGL_MOD_SUPER : 0;
}

static LRESULT
handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
PuglKey key;

setModifiers(view);
switch (message) {
case WM_CREATE:
case WM_SHOWWINDOW:
case WM_SIZE:
RECT rect;
GetClientRect(view->impl->hwnd, &rect);
puglReshape(view, rect.right, rect.bottom);
view->width = rect.right;
view->height = rect.bottom;
break;
case WM_PAINT:
BeginPaint(view->impl->hwnd, &ps);
puglDisplay(view);
EndPaint(view->impl->hwnd, &ps);
break;
case WM_MOUSEMOVE:
if (view->motionFunc) {
view->motionFunc(view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
break;
case WM_LBUTTONDOWN:
processMouseEvent(view, 1, true, lParam);
break;
case WM_MBUTTONDOWN:
processMouseEvent(view, 2, true, lParam);
break;
case WM_RBUTTONDOWN:
processMouseEvent(view, 3, true, lParam);
break;
case WM_LBUTTONUP:
processMouseEvent(view, 1, false, lParam);
break;
case WM_MBUTTONUP:
processMouseEvent(view, 2, false, lParam);
break;
case WM_RBUTTONUP:
processMouseEvent(view, 3, false, lParam);
break;
case WM_MOUSEWHEEL:
if (view->scrollFunc) {
view->event_timestamp_ms = GetMessageTime();
view->scrollFunc(
view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
0.0f, (int16_t)HIWORD(wParam) / (float)WHEEL_DELTA);
}
break;
case WM_MOUSEHWHEEL:
if (view->scrollFunc) {
view->event_timestamp_ms = GetMessageTime();
view->scrollFunc(
view, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam),
(int16_t)HIWORD(wParam) / float(WHEEL_DELTA), 0.0f);
}
break;
case WM_KEYDOWN:
if (view->ignoreKeyRepeat && (lParam & (1 << 30))) {
break;
} // else nobreak
case WM_KEYUP:
view->event_timestamp_ms = GetMessageTime();
if ((key = keySymToSpecial(wParam))) {
if (view->specialFunc) {
view->specialFunc(view, message == WM_KEYDOWN, key);
}
} else if (view->keyboardFunc) {
view->keyboardFunc(view, message == WM_KEYDOWN, wParam);
}
break;
case WM_QUIT:
case LOCAL_CLOSE_MSG:
if (view->closeFunc) {
view->closeFunc(view);
}
break;
default:
return DefWindowProc(
view->impl->hwnd, message, wParam, lParam);
}

return 0;
}

PuglStatus
puglProcessEvents(PuglView* view)
{
MSG msg;
while (PeekMessage(&msg, view->impl->hwnd, 0, 0, PM_REMOVE)) {
handleMessage(view, msg.message, msg.wParam, msg.lParam);
}


if (view->redisplay) {
InvalidateRect(view->impl->hwnd, NULL, FALSE);
}

return PUGL_SUCCESS;
}

LRESULT CALLBACK
wndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
#ifdef _WIN64
PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
#else
PuglView* view = (PuglView*)GetWindowLongPtr(hwnd, GWL_USERDATA);
#endif

switch (message) {
case WM_CREATE:
PostMessage(hwnd, WM_SHOWWINDOW, TRUE, 0);
return 0;
case WM_CLOSE:
PostMessage(hwnd, LOCAL_CLOSE_MSG, wParam, lParam);
return 0;
case WM_DESTROY:
return 0;
default:
if (view) {
return handleMessage(view, message, wParam, lParam);
} else {
return DefWindowProc(hwnd, message, wParam, lParam);
}
}
}

void
puglPostRedisplay(PuglView* view)
{
view->redisplay = true;
}

PuglNativeWindow
puglGetNativeWindow(PuglView* view)
{
return (PuglNativeWindow)view->impl->hwnd;
}

+ 0
- 397
source/modules/dgl/src/pugl/copy/pugl_x11.c View File

@@ -1,397 +0,0 @@
/*
Copyright 2012-2014 David Robillard <http://drobilla.net>
Copyright 2011-2012 Ben Loftis, Harrison Consoles

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted, provided that the above
copyright notice and this permission notice appear in all copies.

THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

/**
@file pugl_x11.c X11 Pugl Implementation.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <GL/gl.h>
#include <GL/glx.h>
#include <X11/Xatom.h>
#include <X11/Xlib.h>
#include <X11/keysym.h>

#include "pugl_internal.h"

struct PuglInternalsImpl {
Display* display;
int screen;
Window win;
GLXContext ctx;
Bool doubleBuffered;
};

/**
Attributes for single-buffered RGBA with at least
4 bits per color and a 16 bit depth buffer.
*/
static int attrListSgl[] = {
GLX_RGBA,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None
};

/**
Attributes for double-buffered RGBA with at least
4 bits per color and a 16 bit depth buffer.
*/
static int attrListDbl[] = {
GLX_RGBA, GLX_DOUBLEBUFFER,
GLX_RED_SIZE, 4,
GLX_GREEN_SIZE, 4,
GLX_BLUE_SIZE, 4,
GLX_DEPTH_SIZE, 16,
None
};

PuglView*
puglCreate(PuglNativeWindow parent,
const char* title,
int width,
int height,
bool resizable,
bool visible)
{
PuglView* view = (PuglView*)calloc(1, sizeof(PuglView));
PuglInternals* impl = (PuglInternals*)calloc(1, sizeof(PuglInternals));
if (!view || !impl) {
return NULL;
}

view->impl = impl;
view->width = width;
view->height = height;

impl->display = XOpenDisplay(0);
impl->screen = DefaultScreen(impl->display);

XVisualInfo* vi = glXChooseVisual(impl->display, impl->screen, attrListDbl);
if (!vi) {
vi = glXChooseVisual(impl->display, impl->screen, attrListSgl);
impl->doubleBuffered = False;
PUGL_LOG("No double buffering available\n");
} else {
impl->doubleBuffered = True;
PUGL_LOG("Double buffered rendering enabled\n");
}

int glxMajor, glxMinor;
glXQueryVersion(impl->display, &glxMajor, &glxMinor);
PUGL_LOGF("GLX Version %d.%d\n", glxMajor, glxMinor);

impl->ctx = glXCreateContext(impl->display, vi, 0, GL_TRUE);

Window xParent = parent
? (Window)parent
: RootWindow(impl->display, impl->screen);

Colormap cmap = XCreateColormap(
impl->display, xParent, vi->visual, AllocNone);

XSetWindowAttributes attr;
memset(&attr, 0, sizeof(XSetWindowAttributes));
attr.colormap = cmap;
attr.border_pixel = 0;

attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask
| ButtonPressMask | ButtonReleaseMask
#ifdef XKEYFOCUSGRAB
| EnterWindowMask
#endif
| PointerMotionMask | StructureNotifyMask;

impl->win = XCreateWindow(
impl->display, xParent,
0, 0, view->width, view->height, 0, vi->depth, InputOutput, vi->visual,
CWBorderPixel | CWColormap | CWEventMask, &attr);

XSizeHints sizeHints;
memset(&sizeHints, 0, sizeof(sizeHints));
if (!resizable) {
sizeHints.flags = PMinSize|PMaxSize;
sizeHints.min_width = width;
sizeHints.min_height = height;
sizeHints.max_width = width;
sizeHints.max_height = height;
XSetNormalHints(impl->display, impl->win, &sizeHints);
}

if (title) {
XStoreName(impl->display, impl->win, title);
}

if (!parent) {
Atom wmDelete = XInternAtom(impl->display, "WM_DELETE_WINDOW", True);
XSetWMProtocols(impl->display, impl->win, &wmDelete, 1);
}

if (visible) {
XMapRaised(impl->display, impl->win);
}

if (glXIsDirect(impl->display, impl->ctx)) {
PUGL_LOG("DRI enabled (to disable, set LIBGL_ALWAYS_INDIRECT=1\n");
} else {
PUGL_LOG("No DRI available\n");
}

XFree(vi);

return view;
}

void
puglDestroy(PuglView* view)
{
if (!view) {
return;
}

glXDestroyContext(view->impl->display, view->impl->ctx);
XDestroyWindow(view->impl->display, view->impl->win);
XCloseDisplay(view->impl->display);
free(view->impl);
free(view);
}

void
puglReshape(PuglView* view, int width, int height)
{
glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);

if (view->reshapeFunc) {
view->reshapeFunc(view, width, height);
} else {
puglDefaultReshape(view, width, height);
}

view->width = width;
view->height = height;
}

void
puglDisplay(PuglView* view)
{
glXMakeCurrent(view->impl->display, view->impl->win, view->impl->ctx);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glLoadIdentity();

if (view->displayFunc) {
view->displayFunc(view);
}

glFlush();
if (view->impl->doubleBuffered) {
glXSwapBuffers(view->impl->display, view->impl->win);
}

view->redisplay = false;
}

static PuglKey
keySymToSpecial(KeySym sym)
{
switch (sym) {
case XK_F1: return PUGL_KEY_F1;
case XK_F2: return PUGL_KEY_F2;
case XK_F3: return PUGL_KEY_F3;
case XK_F4: return PUGL_KEY_F4;
case XK_F5: return PUGL_KEY_F5;
case XK_F6: return PUGL_KEY_F6;
case XK_F7: return PUGL_KEY_F7;
case XK_F8: return PUGL_KEY_F8;
case XK_F9: return PUGL_KEY_F9;
case XK_F10: return PUGL_KEY_F10;
case XK_F11: return PUGL_KEY_F11;
case XK_F12: return PUGL_KEY_F12;
case XK_Left: return PUGL_KEY_LEFT;
case XK_Up: return PUGL_KEY_UP;
case XK_Right: return PUGL_KEY_RIGHT;
case XK_Down: return PUGL_KEY_DOWN;
case XK_Page_Up: return PUGL_KEY_PAGE_UP;
case XK_Page_Down: return PUGL_KEY_PAGE_DOWN;
case XK_Home: return PUGL_KEY_HOME;
case XK_End: return PUGL_KEY_END;
case XK_Insert: return PUGL_KEY_INSERT;
case XK_Shift_L: return PUGL_KEY_SHIFT;
case XK_Shift_R: return PUGL_KEY_SHIFT;
case XK_Control_L: return PUGL_KEY_CTRL;
case XK_Control_R: return PUGL_KEY_CTRL;
case XK_Alt_L: return PUGL_KEY_ALT;
case XK_Alt_R: return PUGL_KEY_ALT;
case XK_Super_L: return PUGL_KEY_SUPER;
case XK_Super_R: return PUGL_KEY_SUPER;
}
return (PuglKey)0;
}

static void
setModifiers(PuglView* view, unsigned xstate, unsigned xtime)
{
view->event_timestamp_ms = xtime;

view->mods = 0;
view->mods |= (xstate & ShiftMask) ? PUGL_MOD_SHIFT : 0;
view->mods |= (xstate & ControlMask) ? PUGL_MOD_CTRL : 0;
view->mods |= (xstate & Mod1Mask) ? PUGL_MOD_ALT : 0;
view->mods |= (xstate & Mod4Mask) ? PUGL_MOD_SUPER : 0;
}

static void
dispatchKey(PuglView* view, XEvent* event, bool press)
{
KeySym sym;
char str[5];
const int n = XLookupString(&event->xkey, str, 4, &sym, NULL);
if (n == 0) {
return;
} else if (n > 1) {
fprintf(stderr, "warning: Unsupported multi-byte key %X\n", (int)sym);
return;
}

const PuglKey special = keySymToSpecial(sym);
if (special && view->specialFunc) {
view->specialFunc(view, press, special);
} else if (!special && view->keyboardFunc) {
view->keyboardFunc(view, press, str[0]);
}
}

PuglStatus
puglProcessEvents(PuglView* view)
{
XEvent event;
while (XPending(view->impl->display) > 0) {
XNextEvent(view->impl->display, &event);
switch (event.type) {
case MapNotify:
puglReshape(view, view->width, view->height);
break;
case ConfigureNotify:
if ((event.xconfigure.width != view->width) ||
(event.xconfigure.height != view->height)) {
puglReshape(view,
event.xconfigure.width,
event.xconfigure.height);
}
break;
case Expose:
if (event.xexpose.count != 0) {
break;
}
puglDisplay(view);
break;
case MotionNotify:
setModifiers(view, event.xmotion.state, event.xmotion.time);
if (view->motionFunc) {
view->motionFunc(view, event.xmotion.x, event.xmotion.y);
}
break;
case ButtonPress:
setModifiers(view, event.xbutton.state, event.xbutton.time);
if (event.xbutton.button >= 4 && event.xbutton.button <= 7) {
if (view->scrollFunc) {
float dx = 0, dy = 0;
switch (event.xbutton.button) {
case 4: dy = 1.0f; break;
case 5: dy = -1.0f; break;
case 6: dx = -1.0f; break;
case 7: dx = 1.0f; break;
}
view->scrollFunc(view,
event.xbutton.x, event.xbutton.y,
dx, dy);
}
break;
}
// nobreak
case ButtonRelease:
setModifiers(view, event.xbutton.state, event.xbutton.time);
if (view->mouseFunc &&
(event.xbutton.button < 4 || event.xbutton.button > 7)) {
view->mouseFunc(view,
event.xbutton.button, event.type == ButtonPress,
event.xbutton.x, event.xbutton.y);
}
break;
case KeyPress:
setModifiers(view, event.xkey.state, event.xkey.time);
dispatchKey(view, &event, true);
break;
case KeyRelease:
setModifiers(view, event.xkey.state, event.xkey.time);
if (view->ignoreKeyRepeat &&
XEventsQueued(view->impl->display, QueuedAfterReading)) {
XEvent next;
XPeekEvent(view->impl->display, &next);
if (next.type == KeyPress &&
next.xkey.time == event.xkey.time &&
next.xkey.keycode == event.xkey.keycode) {
XNextEvent(view->impl->display, &event);
break;
}
}
dispatchKey(view, &event, false);
break;
case ClientMessage:
if (!strcmp(XGetAtomName(view->impl->display,
event.xclient.message_type),
"WM_PROTOCOLS")) {
if (view->closeFunc) {
view->closeFunc(view);
}
}
break;
#ifdef PUGL_GRAB_FOCUS
case EnterNotify:
XSetInputFocus(view->impl->display,
view->impl->win,
RevertToPointerRoot,
CurrentTime);
break;
#endif
default:
break;
}
}

if (view->redisplay) {
puglDisplay(view);
}

return PUGL_SUCCESS;
}

void
puglPostRedisplay(PuglView* view)
{
view->redisplay = true;
}

PuglNativeWindow
puglGetNativeWindow(PuglView* view)
{
return view->impl->win;
}

+ 0
- 116
source/modules/dgl/src/pugl/pugl_osx.diff View File

@@ -1,117 +0,0 @@
--- GIT-other/pugl/pugl/pugl_osx.m 2014-01-27 21:32:59.399032199 +0000
+++ GIT-mine/DPF/dgl/src/pugl/pugl_osx.m 2014-01-27 22:43:50.754197989 +0000
@@ -36,6 +36,7 @@
defer:(BOOL)flag;
- (void) setPuglview:(PuglView*)view;
- (BOOL) windowShouldClose:(id)sender;
+- (BOOL) canBecomeKeyWindow:(id)sender;
@end
@implementation PuglWindow
@@ -70,9 +71,14 @@
return YES;
}
+- (BOOL) canBecomeKeyWindow:(id)sender
+{
+ return NO;
+}
+
@end
-static void
+void
puglDisplay(PuglView* view)
{
if (view->displayFunc) {
@@ -95,13 +101,16 @@
depthBits:(int)numDepthBits;
- (void) reshape;
- (void) drawRect:(NSRect)rect;
+- (void) mouseEntered:(NSEvent*)event;
+- (void) mouseExited:(NSEvent*)event;
- (void) mouseMoved:(NSEvent*)event;
- (void) mouseDragged:(NSEvent*)event;
+- (void) rightMouseDragged:(NSEvent*)event;
- (void) mouseDown:(NSEvent*)event;
- (void) mouseUp:(NSEvent*)event;
- (void) rightMouseDown:(NSEvent*)event;
- (void) rightMouseUp:(NSEvent*)event;
+- (void) scrollWheel:(NSEvent*)event;
- (void) keyDown:(NSEvent*)event;
- (void) keyUp:(NSEvent*)event;
- (void) flagsChanged:(NSEvent*)event;
@@ -170,7 +179,7 @@
- (void) drawRect:(NSRect)rect
{
- display(puglview);
+ puglDisplay(puglview);
glFlush();
glSwapAPPLE();
}
@@ -182,6 +191,10 @@
view->event_timestamp_ms = fmod([ev timestamp] * 1000.0, UINT32_MAX);
+ double ts = [ev timestamp] * 1000.0;
+ ts = (uint32)ts % 500000; //ridiculously large vals won't fit
+ view->event_timestamp_ms = ts;
+
unsigned mods = 0;
mods |= (modifierFlags & NSShiftKeyMask) ? PUGL_MOD_SHIFT : 0;
mods |= (modifierFlags & NSControlKeyMask) ? PUGL_MOD_CTRL : 0;
@@ -332,6 +345,7 @@
struct PuglInternalsImpl {
PuglOpenGLView* glview;
id window;
+ bool isEmbed;
};
PuglView*
@@ -367,6 +381,7 @@
impl->glview = [PuglOpenGLView new];
impl->window = window;
+ impl->isEmbed = (parent != 0);
impl->glview->puglview = view;
[window setContentView:impl->glview];
@@ -396,6 +411,36 @@
PuglStatus
puglProcessEvents(PuglView* view)
{
+ if (! view->impl->isEmbed)
+ {
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ NSEvent* event;
+
+ static const NSUInteger eventMask = (NSLeftMouseDownMask | NSLeftMouseUpMask |
+ NSRightMouseDownMask | NSRightMouseUpMask |
+ NSMouseMovedMask |
+ NSLeftMouseDraggedMask | NSRightMouseDraggedMask |
+ NSMouseEnteredMask | NSMouseExitedMask |
+ NSKeyDownMask | NSKeyUpMask |
+ NSFlagsChangedMask |
+ NSCursorUpdateMask | NSScrollWheelMask);
+
+ for (;;) {
+ event = [view->impl->window
+ nextEventMatchingMask:eventMask
+ untilDate:[NSDate distantPast]
+ inMode:NSEventTrackingRunLoopMode
+ dequeue:YES];
+
+ if (event == nil)
+ break;
+
+ [view->impl->window sendEvent: event];
+ }
+
+ [pool release];
+ }
+
[view->impl->glview setNeedsDisplay: YES];
return PUGL_SUCCESS;

Loading…
Cancel
Save