Commit 35917694 authored by Jaromír Mikeš's avatar Jaromír Mikeš

Imported Upstream version 20160619

parent 5a351fc3
......@@ -8,7 +8,9 @@ export RW=../robtk/
VERSION ?=$(shell date +%Y%m%d)
SUBDIRS = balance.lv2 convoLV2 nodelay.lv2 xfade.lv2 \
midifilter.lv2 meters.lv2 sisco.lv2 tuna.lv2 \
onsettrigger.lv2 mixtri.lv2 fil4.lv2
onsettrigger.lv2 mixtri.lv2 fil4.lv2 \
controlfilter.lv2 midimap.lv2 stereoroute.lv2 \
testsignal.lv2 midigen.lv2
all clean install uninstall: submodule_check $(SUBDIRS)
......
2016-06-17 (0.6.2) Robin Gareus <robin@gareus.org>
* clean up dist tar ball
* support cross-compile build-system
2015-06-27 (0.6.1) Robin Gareus <robin@gareus.org>
* add lv2 version
* specify integers as int in ttl.
......
#!/usr/bin/make -f
# these can be overridden using make variables. e.g.
# make CFLAGS=-O2
# make CXXFLAGS=-O2
# make install DESTDIR=$(CURDIR)/debian/balance_lv2 PREFIX=/usr
#
OPTIMIZATIONS ?= -msse -msse2 -mfpmath=sse -ffast-math -fomit-frame-pointer -O3 -fno-finite-math-only
PREFIX ?= /usr/local
CFLAGS ?= $(OPTIMIZATIONS) -Wall
CXXFLAGS ?= $(OPTIMIZATIONS) -Wall
LIBDIR ?= lib
STRIP=strip
STRIPFLAGS=-s
UISTRIPFLAGS=-s
balance_VERSION?=$(shell git describe --tags HEAD 2>/dev/null | sed 's/-g.*$$//;s/^v//' || echo "LV2")
###############################################################################
......@@ -17,24 +21,40 @@ LOADLIBES=-lm
LV2NAME=balance
LV2GUI=balanceUI
BUNDLE=balance.lv2
BUILDDIR=build/
targets=
override CFLAGS+=-fPIC -std=c99
override CXXFLAGS+=-fPIC
TX=textures/
IS_OSX=
PKG_GL_LIBS=
UNAME=$(shell uname)
ifeq ($(UNAME),Darwin)
IS_OSX=yes
LV2LDFLAGS=-dynamiclib
LIB_EXT=.dylib
EXTENDED_RE=-E
STRIPFLAGS=-u -r -arch all -s lv2syms
UISTRIPFLAGS=-u -r -arch all -s lv2uisyms
targets+=lv2syms lv2uisyms
else
LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic
LIB_EXT=.so
ifneq ($(XWIN),)
IS_WIN=yes
CXX=$(XWIN)-g++
STRIP=$(XWIN)-strip
LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic -Wl,--as-needed
LIB_EXT=.dll
override LDFLAGS += -static-libgcc -static-libstdc++
else
LV2LDFLAGS=-Wl,-Bstatic -Wl,-Bdynamic
LIB_EXT=.so
PKG_GL_LIBS=glu gl
endif
EXTENDED_RE=-r
endif
targets=$(LV2NAME)$(LIB_EXT)
targets+=$(BUILDDIR)$(LV2NAME)$(LIB_EXT)
###############################################################################
# extract versions
......@@ -45,47 +65,49 @@ include git2lv2.mk
ifeq ($(shell pkg-config --exists lv2 || echo no), no)
$(error "LV2 SDK was not found")
else
override CFLAGS+=`pkg-config --cflags lv2`
override CXXFLAGS+=`pkg-config --cflags lv2`
endif
# optional UI
ifeq ($(IS_OSX), yes)
FONTFILE?=/usr/X11/lib/X11/fonts/TTF/VeraBd.ttf
FONTSIZE?=36
FONTSIZE?=32
else
FONTFILE?=/usr/share/fonts/truetype/freefont/FreeSansBold.ttf
FONTSIZE?=40
FONTSIZE?=36
endif
ifeq ($(shell test -f $(FONTFILE) || echo no ), no)
$(warning "!!")
$(warning "!! UI font can not be found on this system")
$(warning "!! install fonts-freefont-ttf or set the FONTFILE variable to a ttf file")
$(warning "!! LV2 GUI will not be built")
$(warning "!!")
FONT_FOUND=no
else
ifeq ($(FONTFILE),verabd.h)
# TODO built-in font - see setBfree
FONT_FOUND=yes
endif
ifeq ($(IS_OSX), yes)
HAVE_UI=$(shell pkg-config --exists ftgl && echo $(FONT_FOUND))
override FONTSIZE=32
else
HAVE_UI=$(shell pkg-config --exists glu gl ftgl && echo $(FONT_FOUND))
ifeq ($(shell test -f $(FONTFILE) || echo no ), no)
$(warning "!!")
$(warning "!! UI font can not be found on this system")
$(warning "!! install fonts-freefont-ttf or set the FONTFILE variable to a ttf file")
$(warning "!! LV2 GUI will not be built")
$(warning "!!")
FONT_FOUND=no
else
FONT_FOUND=yes
endif
endif
HAVE_UI=$(shell pkg-config --exists $(PKG_GL_LIBS) ftgl && echo $(FONT_FOUND))
LV2UIREQ=
# check for LV2 idle thread -- requires 'lv2', atleast_version='1.4.6
ifeq ($(shell pkg-config --atleast-version=1.4.6 lv2 || echo no), no)
UICFLAGS+=-DOLD_SUIL
else
LV2UIREQ=lv2:requiredFeature ui:idleInterface;\\n\\tlv2:extensionData ui:idleInterface;
LV2UIREQ=lv2:requiredFeature ui:idleInterface; lv2:extensionData ui:idleInterface;
endif
# check for lv2_atom_forge_object new in 1.8.1 deprecates lv2_atom_forge_blank
ifeq ($(shell pkg-config --atleast-version=1.8.1 lv2 && echo yes), yes)
override CFLAGS += -DHAVE_LV2_1_8
override CXXFLAGS += -DHAVE_LV2_1_8
endif
ifeq ($(HAVE_UI), yes)
......@@ -93,21 +115,42 @@ ifeq ($(HAVE_UI), yes)
UIDEPS+=$(TX)dial.c $(TX)background.c
UIDEPS+=$(TX)mm_lr.c $(TX)mm_rl.c $(TX)mm_ll.c $(TX)mm_rr.c $(TX)mm_mono.c
UIDEPS+=$(TX)btn_inv.c $(TX)btn_link.c
ifeq ($(IS_OSX), yes)
UIDEPS+=pugl/pugl_osx.m
UILIBS=pugl/pugl_osx.m -framework Cocoa -framework OpenGL
UI_TYPE=CocoaUI
UILIBS+=`pkg-config --variable=libdir ftgl`/libftgl.a `pkg-config --variable=libdir ftgl`/libfreetype.a -lm -mmacosx-version-min=10.5
UILIBS+=`pkg-config --libs zlib`
else
UIDEPS+=pugl/pugl_x11.c
UICFLAGS+=`pkg-config --cflags glu gl`
UILIBS=pugl/pugl_x11.c -lX11 `pkg-config --libs glu gl`
UI_TYPE=X11UI
ifneq ($(XWIN),)
UIDEPS+=pugl/pugl_win.cpp
UICFLAGS+=-DPTW32_STATIC_LIB
UILIBS=pugl/pugl_win.cpp
UILIBS+=`pkg-config --variable=libdir ftgl`/libftgl.a `pkg-config --variable=libdir ftgl`/libfreetype.a
UILIBS+=`pkg-config --libs zlib`
UILIBS+=-lws2_32 -lwinmm -lopengl32 -lglu32 -lgdi32 -lcomdlg32 -lpthread
UI_TYPE=WindowsUI
else
UIDEPS+=pugl/pugl_x11.c
UICFLAGS+=`pkg-config --cflags glu gl`
UILIBS=pugl/pugl_x11.c -lX11
UI_TYPE=X11UI
ifeq ($(STATICBUILD), yes)
UILIBS+=`pkg-config --libs glu`
UILIBS+=`pkg-config --variable=libdir ftgl`/libftgl.a `pkg-config --variable=libdir ftgl`/libfreetype.a
UILIBS+=`pkg-config --libs zlib`
else
UILIBS+=`pkg-config --libs glu ftgl`
endif
UICFLAGS+=-DFONTFILE=\"$(FONTFILE)\"
endif
endif
override CFLAGS+=`pkg-config --cflags ftgl` -DUINQHACK=Blc
UILIBS+=`pkg-config --libs ftgl`
override CFLAGS+=-DFONTFILE=\"$(FONTFILE)\"
override CFLAGS+=-DFONTSIZE=$(FONTSIZE)
targets+=$(LV2GUI)$(LIB_EXT)
UICFLAGS+=`pkg-config --cflags freetype2` `pkg-config --cflags ftgl` -DHAVE_FTGL -DUINQHACK=Blc
UICFLAGS+=-DFONTSIZE=$(FONTSIZE)
targets+=$(BUILDDIR)$(LV2GUI)$(LIB_EXT)
else
$(warning "!!")
$(warning "!! openGL/GLU is not available - GUI disabled")
......@@ -115,44 +158,60 @@ else
$(warning "!!")
endif
# build target definitions
default: all
all: manifest.ttl $(LV2NAME).ttl $(targets)
all: $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(targets)
lv2syms:
echo "_lv2_descriptor" > lv2syms
manifest.ttl: manifest.ttl.in manifest.ui.ttl.in
lv2uisyms:
echo "_lv2ui_descriptor" > lv2uisyms
$(BUILDDIR)manifest.ttl: manifest.ttl.in manifest.ui.ttl.in
@mkdir -p $(BUILDDIR)
sed "s/@LV2NAME@/$(LV2NAME)/;s/@LIB_EXT@/$(LIB_EXT)/" \
manifest.ttl.in > manifest.ttl
manifest.ttl.in > $(BUILDDIR)manifest.ttl
ifeq ($(HAVE_UI), yes)
sed "s/@LV2NAME@/$(LV2NAME)/;s/@LV2GUI@/$(LV2GUI)/;s/@LIB_EXT@/$(LIB_EXT)/;s/@UI_TYPE@/$(UI_TYPE)/" manifest.ui.ttl.in >> manifest.ttl
sed "s/@LV2NAME@/$(LV2NAME)/;s/@LV2GUI@/$(LV2GUI)/;s/@LIB_EXT@/$(LIB_EXT)/;s/@UI_TYPE@/$(UI_TYPE)/" \
manifest.ui.ttl.in >> $(BUILDDIR)manifest.ttl
endif
$(LV2NAME).ttl: $(LV2NAME).ttl.in $(LV2NAME).ui.ttl.in
$(BUILDDIR)$(LV2NAME).ttl: $(LV2NAME).ttl.in $(LV2NAME).ui.ttl.in
@mkdir -p $(BUILDDIR)
sed "s/@VERSION@/lv2:microVersion $(LV2MIC) ;lv2:minorVersion $(LV2MIN) ;/g" \
$(LV2NAME).ttl.in > $(LV2NAME).ttl
$(LV2NAME).ttl.in > $(BUILDDIR)$(LV2NAME).ttl
ifeq ($(HAVE_UI), yes)
sed "s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/;" $(LV2NAME).ui.ttl.in >> $(LV2NAME).ttl
sed "s/@UI_TYPE@/$(UI_TYPE)/;s/@UI_REQ@/$(LV2UIREQ)/;" \
$(LV2NAME).ui.ttl.in >> $(BUILDDIR)$(LV2NAME).ttl
endif
$(LV2NAME)$(LIB_EXT): balance.c uris.h
$(CC) $(CPPFLAGS) $(CFLAGS) \
-o $(LV2NAME)$(LIB_EXT) balance.c \
$(BUILDDIR)$(LV2NAME)$(LIB_EXT): balance.c uris.h
@mkdir -p $(BUILDDIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) \
-o $(BUILDDIR)$(LV2NAME)$(LIB_EXT) balance.c \
-shared $(LV2LDFLAGS) $(LDFLAGS) $(LOADLIBES)
$(STRIP) $(STRIPFLAGS) $(BUILDDIR)$(LV2NAME)$(LIB_EXT)
$(LV2GUI)$(LIB_EXT): ui.c uris.h $(UIDEPS)
$(CC) $(CPPFLAGS) $(CFLAGS) $(UICFLAGS) \
-o $(LV2GUI)$(LIB_EXT) ui.c \
$(BUILDDIR)$(LV2GUI)$(LIB_EXT): ui.c uris.h $(UIDEPS) $(FONTFILE)
@mkdir -p $(BUILDDIR)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(UICFLAGS) \
-o $(BUILDDIR)$(LV2GUI)$(LIB_EXT) ui.c \
-shared $(LV2LDFLAGS) $(LDFLAGS) $(UILIBS)
$(STRIP) $(UISTRIPFLAGS) $(BUILDDIR)$(LV2GUI)$(LIB_EXT)
verabd.h: VeraBd.ttf
xxd -i VeraBd.ttf > verabd.h
# install/uninstall/clean target definitions
install: all
install -d $(DESTDIR)$(LV2DIR)/$(BUNDLE)
install -m755 $(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE)
install -m644 manifest.ttl $(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE)
install -m755 $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE)
install -m644 $(BUILDDIR)manifest.ttl $(BUILDDIR)$(LV2NAME).ttl $(DESTDIR)$(LV2DIR)/$(BUNDLE)
ifeq ($(HAVE_UI), yes)
install -m755 $(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE)
install -m755 $(BUILDDIR)$(LV2GUI)$(LIB_EXT) $(DESTDIR)$(LV2DIR)/$(BUNDLE)
endif
uninstall:
......@@ -163,6 +222,7 @@ uninstall:
-rmdir $(DESTDIR)$(LV2DIR)/$(BUNDLE)
clean:
rm -f manifest.ttl balance.ttl $(LV2NAME)$(LIB_EXT) $(LV2GUI)$(LIB_EXT)
rm -f $(BUILDDIR)manifest.ttl $(BUILDDIR)balance.ttl $(BUILDDIR)$(LV2NAME)$(LIB_EXT) $(BUILDDIR)$(LV2GUI)$(LIB_EXT) lv2syms lv2uisyms
-test -d $(BUILDDIR) && rmdir $(BUILDDIR) || true
.PHONY: clean all install uninstall
......@@ -654,7 +654,7 @@ instantiate(const LV2_Descriptor* descriptor,
const LV2_Feature* const* features)
{
int i;
BalanceControl* self = (BalanceControl*)calloc(1, sizeof(BalanceControl));
BalanceControl* self = (BalanceControl*) calloc(1, sizeof(BalanceControl));
if (!self) return NULL;
for (int i=0; features[i]; ++i) {
......@@ -687,11 +687,11 @@ instantiate(const LV2_Descriptor* descriptor,
self->c_dly[i] = 0;
self->r_ptr[i] = self->w_ptr[i] = 0;
memset(self->buffer[i], 0, sizeof(float) * MAXDELAY);
self->p_peak_inPi[i] = malloc(self->peak_integrate_max * sizeof(double));
self->p_peak_outPi[i] = malloc(self->peak_integrate_max * sizeof(double));
self->p_peak_inPi[i] = (double*) malloc(self->peak_integrate_max * sizeof(double));
self->p_peak_outPi[i] = (double*) malloc(self->peak_integrate_max * sizeof(double));
}
self->p_phase_outPi = malloc(self->phase_integrate_max * sizeof(double));
self->p_phase_outNi = malloc(self->phase_integrate_max * sizeof(double));
self->p_phase_outPi = (double*) malloc(self->phase_integrate_max * sizeof(double));
self->p_phase_outNi = (double*) malloc(self->phase_integrate_max * sizeof(double));
self->uicom_active = 0;
self->c_monomode = 0;
......@@ -712,40 +712,40 @@ connect_port(LV2_Handle instance,
switch ((PortIndex)port) {
case BLC_TRIM:
self->trim = data;
self->trim = (float*) data;
break;
case BLC_PHASEL:
self->phase[C_LEFT] = data;
self->phase[C_LEFT] = (float*) data;
break;
case BLC_PHASER:
self->phase[C_RIGHT] = data;
self->phase[C_RIGHT] = (float*) data;
break;
case BLC_BALANCE:
self->balance = data;
self->balance = (float*) data;
break;
case BLC_UNIYGAIN:
self->unitygain = data;
self->unitygain = (float*) data;
break;
case BLC_MONOIZE:
self->monomode = data;
self->monomode = (float*) data;
break;
case BLC_DLYL:
self->delay[C_LEFT] = data;
self->delay[C_LEFT] = (float*) data;
break;
case BLC_DLYR:
self->delay[C_RIGHT] = data;
self->delay[C_RIGHT] = (float*) data;
break;
case BLC_INL:
self->input[C_LEFT] = data;
self->input[C_LEFT] = (float*) data;
break;
case BLC_INR:
self->input[C_RIGHT] = data;
self->input[C_RIGHT] = (float*) data;
break;
case BLC_OUTL:
self->output[C_LEFT] = data;
self->output[C_LEFT] = (float*) data;
break;
case BLC_OUTR:
self->output[C_RIGHT] = data;
self->output[C_RIGHT] = (float*) data;
break;
case BLC_UINOTIFY:
self->notify = (LV2_Atom_Sequence*)data;
......@@ -854,6 +854,12 @@ static const LV2_Descriptor descriptor = {
extension_data
};
#undef LV2_SYMBOL_EXPORT
#ifdef _WIN32
# define LV2_SYMBOL_EXPORT __declspec(dllexport)
#else
# define LV2_SYMBOL_EXPORT __attribute__ ((visibility ("default")))
#endif
LV2_SYMBOL_EXPORT
const LV2_Descriptor*
lv2_descriptor(uint32_t index)
......
......@@ -213,6 +213,15 @@ typedef void (*PuglScrollFunc)(PuglView* view, int x, int y, float dx, float dy)
*/
typedef void (*PuglSpecialFunc)(PuglView* view, bool press, PuglKey key);
/**
A function called when a filename is selected via file-browser.
@param view The view the event occured in.
@param filename The selected file name or NULL if the dialog was canceled.
*/
typedef void (*PuglFileSelectedFunc)(PuglView* view, const char* filename);
/**
Create a new GL window.
@param parent Parent window, or 0 for top level.
......@@ -318,6 +327,18 @@ puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc);
PUGL_API void
puglSetReshapeFunc(PuglView* view, PuglReshapeFunc reshapeFunc);
/**
Set the function to call on file-browser selections.
*/
PUGL_API void
puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc);
/**
Open a file dialog window.
*/
PUGL_API int
puglOpenFileDialog(PuglView* view, const char *title);
/**
Return the native window handle.
*/
......
......@@ -37,6 +37,7 @@ struct PuglViewImpl {
PuglResizeFunc resizeFunc;
PuglScrollFunc scrollFunc;
PuglSpecialFunc specialFunc;
PuglFileSelectedFunc fileSelectedFunc;
PuglInternals* impl;
......@@ -151,3 +152,9 @@ puglSetSpecialFunc(PuglView* view, PuglSpecialFunc specialFunc)
{
view->specialFunc = specialFunc;
}
void
puglSetFileSelectedFunc(PuglView* view, PuglFileSelectedFunc fileSelectedFunc)
{
view->fileSelectedFunc = fileSelectedFunc;
}
......@@ -151,6 +151,7 @@ __attribute__ ((visibility ("hidden")))
if (self) {
[[self openGLContext] makeCurrentContext];
[self reshape];
[NSOpenGLContext clearCurrentContext];
}
return self;
}
......@@ -168,11 +169,13 @@ __attribute__ ((visibility ("hidden")))
deleting the view (?), so we must have reset puglview to NULL when
this comes around.
*/
[[self openGLContext] makeCurrentContext];
if (puglview->reshapeFunc) {
puglview->reshapeFunc(puglview, width, height);
} else {
puglDefaultReshape(puglview, width, height);
}
[NSOpenGLContext clearCurrentContext];
puglview->width = width;
puglview->height = height;
......@@ -186,9 +189,11 @@ __attribute__ ((visibility ("hidden")))
- (void) drawRect:(NSRect)rect
{
[[self openGLContext] makeCurrentContext];
puglDisplay(puglview);
glFlush();
glSwapAPPLE();
[NSOpenGLContext clearCurrentContext];
}
static unsigned
......@@ -399,6 +404,9 @@ puglCreate(PuglNativeWindow parent,
NSView* pview = (NSView*) parent;
[pview addSubview:impl->glview];
[impl->glview setHidden:NO];
if (!resizable) {
[impl->glview setAutoresizingMask:NSViewNotSizable];
}
} else {
NSString* titleString = [[NSString alloc]
initWithBytes:title
......@@ -421,6 +429,9 @@ puglCreate(PuglNativeWindow parent,
[NSApp activateIgnoringOtherApps:YES];
[window makeFirstResponder:impl->glview];
[window makeKeyAndOrderFront:window];
if (!resizable) {
[window setStyleMask:[window styleMask] & ~NSResizableWindowMask];
}
}
return view;
}
......@@ -458,9 +469,12 @@ puglResize(PuglView* view)
int set_hints; // ignored
view->resize = false;
if (!view->resizeFunc) { return; }
[[view->impl->glview openGLContext] makeCurrentContext];
view->resizeFunc(view, &view->width, &view->height, &set_hints);
[view->impl->window setContentSize:NSMakeSize(view->width, view->height) ];
[view->impl->glview reshape];
[NSOpenGLContext clearCurrentContext];
}
void
......@@ -494,3 +508,56 @@ puglGetNativeWindow(PuglView* view)
{
return (PuglNativeWindow)view->impl->glview;
}
int
puglOpenFileDialog(PuglView* view, const char *title)
{
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setCanChooseFiles:YES];
[panel setCanChooseDirectories:NO];
[panel setAllowsMultipleSelection:NO];
if (title) {
NSString* titleString = [[NSString alloc]
initWithBytes:title
length:strlen(title)
encoding:NSUTF8StringEncoding];
[panel setTitle:titleString];
}
[panel beginWithCompletionHandler:^(NSInteger result) {
bool file_ok = false;
if (result == NSFileHandlingPanelOKButton) {
for (NSURL *url in [panel URLs]) {
if (![url isFileURL]) continue;
//NSLog(@"%@", url.path);
const char *fn= [url.path UTF8String];
file_ok = true;
if (view->fileSelectedFunc) {
view->fileSelectedFunc(view, fn);
}
break;
}
}
if (!file_ok && view->fileSelectedFunc) {
view->fileSelectedFunc(view, NULL);
}
}];
return 0;
}
bool
rtk_osx_open_url (const char* url)
{
NSString* strurl = [[NSString alloc] initWithUTF8String:url];
NSURL* nsurl = [[NSURL alloc] initWithString:strurl];
bool ret = [[NSWorkspace sharedWorkspace] openURL:nsurl];
[strurl release];
[nsurl release];
return ret;
}
......@@ -208,7 +208,7 @@ puglReshape(PuglView* view, int width, int height)
view->height = height;
}
void
static void
puglDisplay(PuglView* view)
{
wglMakeCurrent(view->impl->hdc, view->impl->hglrc);
......@@ -292,7 +292,7 @@ processMouseEvent(PuglView* view, int button, bool press, LPARAM lParam)
} else {
ReleaseCapture();
}
if (view->mouseFunc) {
view->mouseFunc(view, button, press,
GET_X_LPARAM(lParam),
......@@ -365,6 +365,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_MOUSEWHEEL:
if (view->scrollFunc) {
view->event_timestamp_ms = GetMessageTime();
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(view->impl->hwnd, &pt);
view->scrollFunc(
......@@ -374,6 +375,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_MOUSEHWHEEL:
if (view->scrollFunc) {
view->event_timestamp_ms = GetMessageTime();
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
ScreenToClient(view->impl->hwnd, &pt);
view->scrollFunc(
......@@ -382,12 +384,12 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case WM_KEYDOWN:
view->event_timestamp_ms = (GetMessageTime());
if (view->ignoreKeyRepeat && (lParam & (1 << 30))) {
break;
} // else nobreak
case WM_KEYUP:
if (key = keySymToSpecial(wParam)) {
view->event_timestamp_ms = GetMessageTime();
if ((key = keySymToSpecial(wParam))) {
if (view->specialFunc) {
view->specialFunc(view, message == WM_KEYDOWN, key);
}
......@@ -474,3 +476,36 @@ puglGetNativeWindow(PuglView* view)
{
return (PuglNativeWindow)view->impl->hwnd;
}
int
puglOpenFileDialog(PuglView* view, const char *title)
{
char fn[1024] = "";
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFile = fn;
ofn.nMaxFile = 1024;
ofn.lpstrTitle = title;
ofn.lpstrFilter = "All\0*.*\0";
ofn.nFilterIndex = 0;
ofn.lpstrInitialDir = 0;
ofn.Flags = OFN_ENABLESIZING | OFN_FILEMUSTEXIST | OFN_NONETWORKBUTTON | OFN_HIDEREADONLY | OFN_READONLY;
// TODO look into async ofn.lpfnHook, OFN_ENABLEHOOK
// UINT_PTR CALLBACK openFileHook(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
// yet it seems GetOpenFIleName itself won't return anyway.
ofn.hwndOwner = view->impl->hwnd; // modal
if (GetOpenFileName (&ofn)) {
if (view->fileSelectedFunc) {
view->fileSelectedFunc(view, fn);
}