From 48cab9c5066d5ab4f9edf193852f6f75baca11cc Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 5 Dec 2017 17:59:19 -0500 Subject: [PATCH 001/144] win32_utf8: add SHGetSpecialFolderPathUTF8() (do not define it to SHGetSpecialFolderPath because shlobj.h conflicts often, force code to call UTF8 version directly) --- WDL/win32_utf8.c | 14 ++++++++++++++ WDL/win32_utf8.h | 2 ++ 2 files changed, 16 insertions(+) diff --git a/WDL/win32_utf8.c b/WDL/win32_utf8.c index b88a5713..dc29ab24 100644 --- a/WDL/win32_utf8.c +++ b/WDL/win32_utf8.c @@ -374,6 +374,20 @@ BOOL GetSaveFileNameUTF8(LPOPENFILENAME lpofn) return GetOpenSaveFileNameUTF8(lpofn,TRUE); } +BOOL SHGetSpecialFolderPathUTF8(HWND hwndOwner, LPTSTR lpszPath, int pszPathLen, int csidl, BOOL create) +{ + if (lpszPath AND_IS_NOT_WIN9X) + { + WCHAR tmp[4096]; + if (SHGetSpecialFolderPathW(hwndOwner,tmp,csidl,create)) + { + return WideCharToMultiByte(CP_UTF8,0,tmp,-1,lpszPath,pszPathLen,NULL,NULL) > 0; + } + } + return SHGetSpecialFolderPathA(hwndOwner,lpszPath,csidl,create); +} + + #if _MSC_VER > 1700 && defined(_WIN64) BOOL SHGetPathFromIDListUTF8(const struct _ITEMIDLIST __unaligned *pidl, LPSTR pszPath, int pszPathLen) #else diff --git a/WDL/win32_utf8.h b/WDL/win32_utf8.h index 4768d023..fc17f909 100644 --- a/WDL/win32_utf8.h +++ b/WDL/win32_utf8.h @@ -46,6 +46,8 @@ WDL_WIN32_UTF8_IMPL BOOL SHGetPathFromIDListUTF8(const struct _ITEMIDLIST __unal WDL_WIN32_UTF8_IMPL BOOL SHGetPathFromIDListUTF8(const struct _ITEMIDLIST *pidl, LPSTR pszPath, int pszPathLen); #endif +WDL_WIN32_UTF8_IMPL BOOL SHGetSpecialFolderPathUTF8(HWND hwndOwner, LPTSTR lpszPath, int pszPathLen, int csidl, BOOL create); + WDL_WIN32_UTF8_IMPL struct _ITEMIDLIST *SHBrowseForFolderUTF8(struct _browseinfoA *browseInfoA); WDL_WIN32_UTF8_IMPL int WDL_UTF8_SendBFFM_SETSEL(HWND hwnd, const char *str); // sends BFFM_SETSELECTIONA or BFFM_SETSELECTIONW From 6da12705244136e82d907d6cf39738301b71a539 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 5 Dec 2017 18:37:58 -0500 Subject: [PATCH 002/144] jnetlib: use SO_REUSEADDR when listening on win32 -- from 78bcd3c2 --- WDL/jnetlib/listen.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WDL/jnetlib/listen.cpp b/WDL/jnetlib/listen.cpp index 32676f23..df20f1c7 100644 --- a/WDL/jnetlib/listen.cpp +++ b/WDL/jnetlib/listen.cpp @@ -22,10 +22,8 @@ JNL_Listen::JNL_Listen(short port, unsigned int which_interface) { struct sockaddr_in sin; SET_SOCK_BLOCK(m_socket,0); -#ifndef _WIN32 int bflag = 1; - setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &bflag, sizeof(bflag)); -#endif + setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char*)&bflag, sizeof(bflag)); memset((char *) &sin, 0,sizeof(sin)); sin.sin_family = AF_INET; sin.sin_port = htons( (short) port ); From eb3bea0046d2fa4166a00a535dab3e742028628d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 1 Dec 2017 13:31:31 -0500 Subject: [PATCH 003/144] win32_utf8: fix GetWindowText()/GetDlgItemText() with all UTF-8 characters for combo-boxes that are not editable -- from f5d68c86 --- WDL/win32_utf8.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/WDL/win32_utf8.c b/WDL/win32_utf8.c index dc29ab24..24d4d1a8 100644 --- a/WDL/win32_utf8.c +++ b/WDL/win32_utf8.c @@ -71,6 +71,33 @@ int GetWindowTextUTF8(HWND hWnd, LPTSTR lpString, int nMaxCount) { HWND h2=FindWindowEx(hWnd,NULL,"Edit",NULL); if (h2) hWnd=h2; + else + { + // get via selection + int sel = (int) SendMessage(hWnd,CB_GETCURSEL,0,0); + if (sel>=0) + { + int len = (int) SendMessage(hWnd,CB_GETLBTEXTLEN,sel,0); + char *p = lpString; + if (len > nMaxCount-1) + { + p = (char*)calloc(len+1,1); + len = nMaxCount-1; + } + lpString[0]=0; + if (p) + { + SendMessage(hWnd,CB_GETLBTEXT,sel,(LPARAM)p); + if (p!=lpString) + { + memcpy(lpString,p,len); + lpString[len]=0; + free(p); + } + return len; + } + } + } } // prevent large values of nMaxCount from allocating memory unless the underlying text is big too From b5dae3fac329d900cbed37d2f625a6a68060f27f Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 29 Dec 2017 17:38:53 -0500 Subject: [PATCH 004/144] swell: define TVS_LINESATROOT as no-op -- from b31a5628 --- WDL/swell/swell-dlggen.h | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/swell/swell-dlggen.h b/WDL/swell/swell-dlggen.h index ef7447af..301777d1 100644 --- a/WDL/swell/swell-dlggen.h +++ b/WDL/swell/swell-dlggen.h @@ -150,6 +150,7 @@ struct SWELL_DlgResourceEntry #define TBS_BOTH 0 #define LBS_NOINTEGRALHEIGHT 0 #define TVS_HASLINES 0 +#define TVS_LINESATROOT 0 #define TVS_SHOWSELALWAYS 0 #define TVS_HASBUTTONS 0 #define BS_FLAT 0 From f9b5585cd9c4f145ab088e108497af55b8f87190 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 6 Jan 2018 08:53:53 -0500 Subject: [PATCH 005/144] LICE: add curverasterbuffer.h utility -- from f0adfcdb --- WDL/lice/curverasterbuffer.h | 113 +++++++++++++++++++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 WDL/lice/curverasterbuffer.h diff --git a/WDL/lice/curverasterbuffer.h b/WDL/lice/curverasterbuffer.h new file mode 100644 index 00000000..f5423248 --- /dev/null +++ b/WDL/lice/curverasterbuffer.h @@ -0,0 +1,113 @@ +#ifndef _LICE_CURVE_RASTER_BUFFER_H_ +#define _LICE_CURVE_RASTER_BUFFER_H_ + +class CurveRasterBuffer +{ + static void CopyPixelNoClip(LICE_IBitmap *bmp, int x, int y, LICE_pixel col, double alpha) + { + LICE_pixel *p=bmp->getBits()+y*bmp->getRowSpan()+x; + if (*p == col || alpha <= 0.0) return; + + if (alpha >= 1.0) + { + *p=col; + return; + } + + const int ia=256-(int)(alpha*256.0); + int r=LICE_GETR(col), g=LICE_GETG(col), b=LICE_GETB(col); + LICE_pixel_chan *c=(LICE_pixel_chan*)p; + c[LICE_PIXEL_R]=r+((c[LICE_PIXEL_R]-r)*ia)/256; + c[LICE_PIXEL_G]=g+((c[LICE_PIXEL_G]-g)*ia)/256; + c[LICE_PIXEL_B]=b+((c[LICE_PIXEL_B]-b)*ia)/256; + } + + static void DrawSlice(LICE_IBitmap* bmp, int x, double y1, double y2, int pxh, LICE_pixel color, float alpha) + { + const int iy1=(int)y1, iy2=(int)y2; + + if (iy1 == iy2) + { + if (iy1 >= 0 && iy1 < pxh) CopyPixelNoClip(bmp, x, iy1, color, (y2-y1)*alpha); + } + else + { + if (iy1 >= 0 && iy1 < pxh) CopyPixelNoClip(bmp, x, iy1, color, (1+iy1-y1)*alpha); + + if (iy2 > iy1+1) + { + int iy; + const int n=min(iy2, pxh); + for (iy=max(iy1+1, 0); iy < n; ++iy) + { + CopyPixelNoClip(bmp, x, iy, color, alpha); + } + } + + if (iy2 >= 0 && iy2 < pxh) CopyPixelNoClip(bmp, x, iy2, color, (y2-iy2)*alpha); + } + } + + public: + int xext[2],bmw; + float *sb; + + CurveRasterBuffer(int w, WDL_TypedBuf *sbuf) + { + xext[0]=bmw=w; + xext[1]=0; + sb = sbuf->ResizeOK(w*2,false); + } + + void addpt(int xpos, double ypos) + { + if (xpos >= 0 && xpos < bmw) + { + float *p = sb + xpos*2; + const int ext0=xext[0], ext1=xext[1]; + if (ext0 <= ext1) // existing range + { + if (xpos < ext0) + { + memset(p+2, 0, (ext0-xpos-1)*2*sizeof(*p)); + p[0]=p[1]=ypos; + xext[0]=xpos; + } + else if (xpos > ext1) + { + memset(sb + (ext1+1)*2, 0, (xpos-(ext1+1))*2*sizeof(*p)); + p[0]=p[1]=ypos; + xext[1]=xpos; + } + else if (p[0] == 0.0 && p[1] == 0.0) p[0] = p[1] = ypos; + else + { + if (ypos < p[0]) p[0] = ypos; + else if (ypos > p[1]) p[1] = ypos; + } + } + else // first point + { + xext[0]=xext[1] = xpos; + p[0]=p[1]=ypos; + } + } + } + + void Draw(LICE_IBitmap *bm, LICE_pixel color, float alpha) + { + const int bmh = bm->getHeight(); + const int xmax = xext[1]; + int x = xext[0]; + const float *sbuf = sb+x*2; + for (; x <= xmax; x ++) + { + const double v1 = sbuf[0], v2 = sbuf[1]; + if (v2>v1) DrawSlice(bm, x,v1,v2, bmh, color,alpha); + sbuf+= 2; + } + } +}; + + +#endif From 02de2a7e0ff007e83fb34830e8a866c0397d7acf Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 6 Jan 2018 14:54:34 -0500 Subject: [PATCH 006/144] swell: support compiling 32-bit with latest SDKs and 10.4 ostensibly supported -- from 2bce5785 --- WDL/swell/swell-gdi.mm | 4 ++-- WDL/swell/swell-internal.h | 14 ++++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/WDL/swell/swell-gdi.mm b/WDL/swell/swell-gdi.mm index 1080b8e8..0a4be578 100644 --- a/WDL/swell/swell-gdi.mm +++ b/WDL/swell/swell-gdi.mm @@ -75,12 +75,12 @@ static int SWELL_GDI_GetOSXVersion() #ifndef SWELL_NO_CORETEXT static bool IsCoreTextSupported() { -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 +#ifdef SWELL_ATSUI_TEXT_SUPPORT return SWELL_GDI_GetOSXVersion() >= 0x1050 && CTFontCreateWithName && CTLineDraw && CTFramesetterCreateWithAttributedString && CTFramesetterCreateFrame && CTFrameGetLines && CTLineGetTypographicBounds && CTLineCreateWithAttributedString && CTFontCopyPostScriptName ; #else - // targetting 10.5+, CT is always valid + // no ATSUI, targetting 10.5+, CT is always valid return true; #endif } diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h index ab118cbb..864daa4b 100644 --- a/WDL/swell/swell-internal.h +++ b/WDL/swell/swell-internal.h @@ -471,14 +471,12 @@ typedef struct WindowPropRec // 10.4 SDK #define SWELL_NO_CORETEXT #define SWELL_ATSUI_TEXT_SUPPORT -#else - -#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -#ifndef __LP64__ -#define SWELL_ATSUI_TEXT_SUPPORT -#endif -#endif - +#elif !defined(__LP64__) + #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 + #ifndef MAC_OS_X_VERSION_10_9 // not sure when ATSUI was dropped completely, definitely gone in 10.13! + #define SWELL_ATSUI_TEXT_SUPPORT + #endif + #endif #endif struct HGDIOBJ__ From 9bebb228dc62de6fc703b1134231a639cdc0e0dd Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 9 Jan 2018 17:02:03 -0500 Subject: [PATCH 007/144] mac compile tweaks -- from 0519829c --- WDL/wingui/virtwnd-nsaccessibility.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/wingui/virtwnd-nsaccessibility.mm b/WDL/wingui/virtwnd-nsaccessibility.mm index 3392d869..27a55a41 100644 --- a/WDL/wingui/virtwnd-nsaccessibility.mm +++ b/WDL/wingui/virtwnd-nsaccessibility.mm @@ -2,6 +2,7 @@ #include "virtwnd-controls.h" +#include @class VWndNSAccessibility; static VWndNSAccessibility *GetVWndNSAccessible(WDL_VWnd *vwnd); From 34c1b5f3d2cbe46ed020cf5191564e4b95114c77 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 9 Jan 2018 21:13:32 -0500 Subject: [PATCH 008/144] has_strings.h: fix typo -- from e688f511 --- WDL/has_strings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/has_strings.h b/WDL/has_strings.h index dc307a53..3547bbff 100644 --- a/WDL/has_strings.h +++ b/WDL/has_strings.h @@ -1,5 +1,5 @@ #ifndef _WDL_HASSTRINGS_H_ -#define _WDL_HASSTRINGS_H +#define _WDL_HASSTRINGS_H_ #ifndef WDL_HASSTRINGS_EXPORT #define WDL_HASSTRINGS_EXPORT From 1664180f5e041412b8fc3631ef5a85a2dd00b3c2 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 11 Jan 2018 18:38:00 -0500 Subject: [PATCH 009/144] LICE: use const char* for parameters to LICE_Load*FromResource() Existing callers will need to be updated to use MAKEINTRESOURCE() on the calling side, but in general it should be ABI-backwards-compatible. -- from b818e249 --- WDL/lice/lice.h | 8 ++++---- WDL/lice/lice_bmp.cpp | 4 ++-- WDL/lice/lice_ico.cpp | 4 ++-- WDL/lice/lice_jpg.cpp | 4 ++-- WDL/lice/lice_png.cpp | 4 ++-- WDL/lice/test/main.cpp | 4 ++-- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/WDL/lice/lice.h b/WDL/lice/lice.h index 0722cde5..383b1082 100644 --- a/WDL/lice/lice.h +++ b/WDL/lice/lice.h @@ -294,19 +294,19 @@ bool LICE_ImageIsSupported(const char *filename); // must be a filename that en // pass a bmp if you wish to load it into that bitmap. note that if it fails bmp will not be deleted. LICE_IBitmap *LICE_LoadPNG(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success LICE_IBitmap *LICE_LoadPNGFromMemory(const void *data_in, int buflen, LICE_IBitmap *bmp=NULL); -LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, const char *resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success #ifndef _WIN32 LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success #endif LICE_IBitmap *LICE_LoadBMP(const char *filename, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, const char *resid, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success LICE_IBitmap *LICE_LoadIcon(const char *filename, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success -LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, int resid, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, const char *resid, int reqiconsz=16, LICE_IBitmap *bmp=NULL); // returns a bitmap (bmp if nonzero) on success LICE_IBitmap *LICE_LoadJPG(const char *filename, LICE_IBitmap *bmp=NULL); -LICE_IBitmap* LICE_LoadJPGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap* bmp = 0); +LICE_IBitmap* LICE_LoadJPGFromResource(HINSTANCE hInst, const char *resid, LICE_IBitmap* bmp = 0); LICE_IBitmap *LICE_LoadGIF(const char *filename, LICE_IBitmap *bmp=NULL, int *nframes=NULL); // if nframes set, will be set to number of images (stacked vertically), otherwise first frame used diff --git a/WDL/lice/lice_bmp.cpp b/WDL/lice/lice_bmp.cpp index ce637458..cd03de50 100644 --- a/WDL/lice/lice_bmp.cpp +++ b/WDL/lice/lice_bmp.cpp @@ -72,9 +72,9 @@ LICE_IBitmap *LICE_LoadBMP(const char *filename, LICE_IBitmap *bmp) // returns a } #ifdef _WIN32 -LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadBMPFromResource(HINSTANCE hInst, const char *resid, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success { - HBITMAP bm=(HBITMAP) LoadImage(hInst,MAKEINTRESOURCE(resid),IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION); + HBITMAP bm=(HBITMAP) LoadImage(hInst,resid,IMAGE_BITMAP,0,0,LR_CREATEDIBSECTION); if (!bm) return 0; LICE_IBitmap *ret=hbmToBit(bm,bmp); diff --git a/WDL/lice/lice_ico.cpp b/WDL/lice/lice_ico.cpp index acfb81e2..c3be7af6 100644 --- a/WDL/lice/lice_ico.cpp +++ b/WDL/lice/lice_ico.cpp @@ -140,11 +140,11 @@ LICE_IBitmap *LICE_LoadIcon(const char *filename, int reqiconsz, LICE_IBitmap *b return ret; } -LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, int resid, int reqiconsz, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success +LICE_IBitmap *LICE_LoadIconFromResource(HINSTANCE hInst, const char *resid, int reqiconsz, LICE_IBitmap *bmp) // returns a bitmap (bmp if nonzero) on success { #ifdef _WIN32 if (reqiconsz<1) reqiconsz=16; - HICON icon = (HICON)LoadImage(hInst,MAKEINTRESOURCE(resid),IMAGE_ICON,reqiconsz,reqiconsz,0); + HICON icon = (HICON)LoadImage(hInst,resid,IMAGE_ICON,reqiconsz,reqiconsz,0); if (!icon) return 0; LICE_IBitmap *ret=icoToBitmap(icon,bmp); diff --git a/WDL/lice/lice_jpg.cpp b/WDL/lice/lice_jpg.cpp index ccf4902a..327269ab 100644 --- a/WDL/lice/lice_jpg.cpp +++ b/WDL/lice/lice_jpg.cpp @@ -54,10 +54,10 @@ static void LICEJPEG_skip_input_data(j_decompress_ptr cinfo, long num_bytes) static void LICEJPEG_term_source(j_decompress_ptr cinfo) {} -LICE_IBitmap *LICE_LoadJPGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) +LICE_IBitmap *LICE_LoadJPGFromResource(HINSTANCE hInst, const char *resid, LICE_IBitmap *bmp) { #ifdef _WIN32 - HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "JPG"); + HRSRC hResource = FindResource(hInst, resid, "JPG"); if(!hResource) return NULL; DWORD imageSize = SizeofResource(hInst, hResource); diff --git a/WDL/lice/lice_png.cpp b/WDL/lice/lice_png.cpp index cb26a216..bf08efee 100644 --- a/WDL/lice/lice_png.cpp +++ b/WDL/lice/lice_png.cpp @@ -309,10 +309,10 @@ LICE_IBitmap *LICE_LoadPNGFromMemory(const void *data_in, int buflen, LICE_IBitm free(row_pointers); return bmp; } -LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, int resid, LICE_IBitmap *bmp) +LICE_IBitmap *LICE_LoadPNGFromResource(HINSTANCE hInst, const char *resid, LICE_IBitmap *bmp) { #ifdef _WIN32 - HRSRC hResource = FindResource(hInst, MAKEINTRESOURCE(resid), "PNG"); + HRSRC hResource = FindResource(hInst, resid, "PNG"); if(!hResource) return NULL; DWORD imageSize = SizeofResource(hInst, hResource); diff --git a/WDL/lice/test/main.cpp b/WDL/lice/test/main.cpp index 57296b1c..b8bbb014 100644 --- a/WDL/lice/test/main.cpp +++ b/WDL/lice/test/main.cpp @@ -985,8 +985,8 @@ WDL_DLGRET WINAPI dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) //jpg=LICE_LoadJPG("C:/turds.jpg"); #ifdef _WIN32 - bmp = LICE_LoadPNGFromResource(g_hInstance, IDC_PNG1); - icon = LICE_LoadIconFromResource(g_hInstance, IDI_MAIN, 0); + bmp = LICE_LoadPNGFromResource(g_hInstance, MAKEINTRESOURCE(IDC_PNG1)); + icon = LICE_LoadIconFromResource(g_hInstance, MAKEINTRESOURCE(IDI_MAIN), 0); #else bmp = LICE_LoadPNGFromNamedResource("image.png"); From 8b14a0b143a07decac32fe6e57e72392b412b1b2 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 13 Jan 2018 16:27:45 -0500 Subject: [PATCH 010/144] xmlparse: add support for non-sorted XML attributes -- from 42e208d4 --- WDL/xmlparse.h | 40 ++++++++++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 8 deletions(-) diff --git a/WDL/xmlparse.h b/WDL/xmlparse.h index f14313d4..88c22f2b 100644 --- a/WDL/xmlparse.h +++ b/WDL/xmlparse.h @@ -37,8 +37,9 @@ class wdl_xml_element { static int attr_cmp(char **a, char **b) { return strcmp(*a,*b); } static void attr_free(char *a) { free(a); } public: - wdl_xml_element(const char *_name, int _line, int _col) : - attributes(attr_cmp,NULL,attr_free,attr_free), name(strdup(_name)), line(_line), col(_col) { } + wdl_xml_element(const char *_name, int _line, int _col, bool _sort_attr=true) : + attributes(attr_cmp,NULL,attr_free,attr_free), name(strdup(_name)), line(_line), col(_col), + m_sort_attributes(_sort_attr) { } ~wdl_xml_element() { free(name); elements.Empty(true); } WDL_PtrList elements; @@ -47,20 +48,32 @@ class wdl_xml_element { char *name; int line, col; + bool m_sort_attributes; const char *get_attribute(const char *v, const char *def=NULL) const { + if (!m_sort_attributes) + { + const int n = attributes.GetSize(); + for (int x = 0; x < n; x ++) + { + char *key = NULL; + const char *val = attributes.Enumerate(x,&key); + if (key && !strcmp(key,v)) return val; + } + } return attributes.Get((char*)v,(char*)def); } }; class wdl_xml_parser { public: - wdl_xml_parser(const char *rdptr, int rdptr_len) : + wdl_xml_parser(const char *rdptr, int rdptr_len, bool sort_attributes=true) : element_xml(NULL), element_root(NULL), m_rdptr((const unsigned char *)rdptr), m_err(NULL), m_rdptr_len(rdptr_len), m_line(1), m_col(0), m_lastchar(0), - m_last_line(1),m_last_col(0) + m_last_line(1),m_last_col(0), + m_sort_attributes(sort_attributes) { } virtual ~wdl_xml_parser() @@ -92,12 +105,14 @@ class wdl_xml_parser { int getLine() const { return m_last_line; } int getCol() const { return m_last_col; } + private: WDL_HeapBuf m_tok; const unsigned char *m_rdptr; const char *m_err; int m_rdptr_len, m_line, m_col, m_lastchar, m_last_line,m_last_col; + bool m_sort_attributes; virtual int moredata(const char **dataOut) { return 0; } @@ -305,7 +320,12 @@ class wdl_xml_parser { char *attr_name = strdup(tok); if (!attr_name) { m_err="malloc fail"; break; } - if (elem->attributes.Get(attr_name)) { m_err="attribute specified more than once"; break; } + if (m_sort_attributes && + elem->attributes.Get(attr_name)) + { + m_err="attribute specified more than once"; + break; + } tok = get_tok(); if (!tok) break; @@ -324,7 +344,11 @@ class wdl_xml_parser { memcpy(value,tok+1,tok_len-2); value[tok_len-2]=0; - elem->attributes.Insert(attr_name,value); + if (m_sort_attributes) + elem->attributes.Insert(attr_name,value); + else + elem->attributes.AddUnsorted(attr_name,value); + attr_name = NULL; } free(attr_name); @@ -451,7 +475,7 @@ class wdl_xml_parser { { if (elem || cnt || element_xml) return "') return "= '0' && *tok <= '9')) return "element name must not begin with .- or number"; - wdl_xml_element *sub = new wdl_xml_element(tok,start_line,start_col); + wdl_xml_element *sub = new wdl_xml_element(tok,start_line,start_col,m_sort_attributes); if (elem) elem->elements.Add(sub); else element_root = sub; From 1606f187280e4f8f9256570f915df28959ab2ad4 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 13 Jan 2018 17:10:14 -0500 Subject: [PATCH 011/144] xmlparse: store state of whether element had discrete close tag -- from 29b979bb --- WDL/xmlparse.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WDL/xmlparse.h b/WDL/xmlparse.h index 88c22f2b..7a22c5e4 100644 --- a/WDL/xmlparse.h +++ b/WDL/xmlparse.h @@ -39,7 +39,7 @@ class wdl_xml_element { public: wdl_xml_element(const char *_name, int _line, int _col, bool _sort_attr=true) : attributes(attr_cmp,NULL,attr_free,attr_free), name(strdup(_name)), line(_line), col(_col), - m_sort_attributes(_sort_attr) { } + m_sort_attributes(_sort_attr), m_has_discrete_close(false) { } ~wdl_xml_element() { free(name); elements.Empty(true); } WDL_PtrList elements; @@ -49,6 +49,7 @@ class wdl_xml_element { char *name; int line, col; bool m_sort_attributes; + bool m_has_discrete_close; const char *get_attribute(const char *v, const char *def=NULL) const { @@ -503,6 +504,7 @@ class wdl_xml_parser { tok = get_tok(); if (!tok || tok[0] != '>') return "expected > following m_has_discrete_close = true; return NULL; } else From ef4e45735ac86da45de6bae1b0a378b4199ee894 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 16 Jan 2018 20:07:20 -0500 Subject: [PATCH 012/144] add volatile wdl_atomic_incr/decr versions -- from 1de1aa03 --- WDL/wdlatomic.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WDL/wdlatomic.h b/WDL/wdlatomic.h index 8bc93453..93f59ff1 100644 --- a/WDL/wdlatomic.h +++ b/WDL/wdlatomic.h @@ -5,11 +5,15 @@ static int wdl_atomic_incr(int *v) { return (int) InterlockedIncrement((LONG *)v); } static int wdl_atomic_decr(int *v) { return (int) InterlockedDecrement((LONG *)v); } +static int wdl_atomic_incr(volatile int *v) { return (int) InterlockedIncrement((LONG *)v); } +static int wdl_atomic_decr(volatile int *v) { return (int) InterlockedDecrement((LONG *)v); } #elif (!defined(__APPLE__) || !defined(__ppc__)) && (defined(__clang__) || (defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)))) static int wdl_atomic_incr(int *v) { return __sync_add_and_fetch(v,1); } static int wdl_atomic_decr(int *v) { return __sync_add_and_fetch(v,~0); } +static int wdl_atomic_incr(volatile int *v) { return __sync_add_and_fetch(v,1); } +static int wdl_atomic_decr(volatile int *v) { return __sync_add_and_fetch(v,~0); } #elif defined(__APPLE__) // used by GCC < 4.2 on OSX @@ -17,6 +21,8 @@ static int wdl_atomic_decr(int *v) { return __sync_add_and_fetch(v,~0); } static int wdl_atomic_incr(int *v) { return (int) OSAtomicIncrement32Barrier((int32_t*)v); } static int wdl_atomic_decr(int *v) { return (int) OSAtomicDecrement32Barrier((int32_t*)v); } +static int wdl_atomic_incr(volatile int *v) { return (int) OSAtomicIncrement32Barrier((int32_t*)v); } +static int wdl_atomic_decr(volatile int *v) { return (int) OSAtomicDecrement32Barrier((int32_t*)v); } #else // unsupported! From 8d7808dbeefdf944e570b3048be2cbe517bdfcfd Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 16 Jan 2018 20:08:38 -0500 Subject: [PATCH 013/144] WDL_SharedMutex uses volatile keyword for ICC v18 32-bit issue -- from 9c119d71 --- WDL/mutex.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/mutex.h b/WDL/mutex.h index 45685069..0af8e08b 100644 --- a/WDL/mutex.h +++ b/WDL/mutex.h @@ -123,7 +123,7 @@ class WDL_Mutex { } #ifdef _DEBUG - int _debug_cnt; + volatile int _debug_cnt; #endif private: @@ -208,7 +208,7 @@ class WDL_SharedMutex private: WDL_Mutex m_mutex; - int m_sharedcnt; + volatile int m_sharedcnt; // prevent callers from copying accidentally WDL_SharedMutex(const WDL_SharedMutex &cp) From e1bd949e2aa62fc677ee67cba6ad2e34e5284fd8 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 29 Jan 2018 11:16:55 -0500 Subject: [PATCH 014/144] non-windows support for file creation time, make time conversions consistent between swell and wdl_dirscan -- from dd912224 --- WDL/dirscan.h | 15 +++++++++++++-- WDL/swell/swell.cpp | 5 +++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/WDL/dirscan.h b/WDL/dirscan.h index f3a08511..56bd3e98 100644 --- a/WDL/dirscan.h +++ b/WDL/dirscan.h @@ -225,8 +225,19 @@ class WDL_DirScan DWORD GetFileAttributes() const { return m_fd.dwFileAttributes; } #elif defined(_WDL_SWELL_H_) - // todo: compat for more of these functions - + void GetCurrentCreationTime(FILETIME *ft) + { + char tmp[2048]; + snprintf(tmp,sizeof(tmp),"%s/%s",m_leading_path.Get(),GetCurrentFN()); + struct stat64 st={0,}; + stat64(tmp,&st); + unsigned long long a=(unsigned long long)st.st_ctime; // seconds since january 1st, 1970 + a+=11644473600ull; // 1601->1970 + a*=10000000; // seconds to 1/10th microseconds (100 nanoseconds) + ft->dwLowDateTime=a & 0xffffffff; + ft->dwHighDateTime=a>>32; + } + void GetCurrentLastWriteTime(FILETIME *ft) { char tmp[2048]; diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index ac7db7d2..69f3dd98 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -72,9 +72,10 @@ DWORD GetTickCount() static void intToFileTime(time_t t, FILETIME *out) { + // see WDL_DirScan::GetCurrentLastWriteTime and similar unsigned long long a=(unsigned long long)t; // seconds since january 1st, 1970 - a+=(60*60*24*(365*4+1)/4)*(long long)(1970-1601); // this is approximate - a*=1000*10000; // seconds to 1/10th microseconds (100 nanoseconds) + a += 11644473600ull; // 1601-1970 + a *= 10000000; // seconds to 1/10th microseconds (100 nanoseconds) out->dwLowDateTime=a & 0xffffffff; out->dwHighDateTime=a>>32; } From b7cf6cc2a4f65ead64acad3898a80b7ca38784b8 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 9 Feb 2018 16:15:19 -0500 Subject: [PATCH 015/144] eel_lice: allow very small sizes for custom UIs -- from b547dd0e --- WDL/eel2/eel_lice.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index 20cd7c78..c217207d 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -2543,6 +2543,13 @@ LRESULT WINAPI eel_lice_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar } } return 0; + case WM_GETMINMAXINFO: + { + LPMINMAXINFO p=(LPMINMAXINFO)lParam; + if (p->ptMinTrackSize.x > 10) p->ptMinTrackSize.x = 10; + if (p->ptMinTrackSize.y > 10) p->ptMinTrackSize.y = 10; + } + return 0; } return DefWindowProc(hwnd,uMsg,wParam,lParam); From 72070c7f74159d48523e5892997e1909dd4fdfa0 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 10 Feb 2018 14:55:49 -0500 Subject: [PATCH 016/144] WDL_makeSearchFilter() clears search term list when passed an empty string -- from 29daaaa7 --- WDL/has_strings.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/has_strings.h b/WDL/has_strings.h index 3547bbff..fb0e514a 100644 --- a/WDL/has_strings.h +++ b/WDL/has_strings.h @@ -181,7 +181,7 @@ WDL_HASSTRINGS_EXPORT bool WDL_hasStrings(const char *name, const LineParser *lp WDL_HASSTRINGS_EXPORT bool WDL_makeSearchFilter(const char *flt, LineParser *lp) { - if (!lp || !flt || !*flt) return false; + if (!lp || !flt) return false; #ifdef WDL_LINEPARSER_HAS_LINEPARSERINT if (lp->parse_ex(flt,true,false,true)) // allow unterminated quotes @@ -189,7 +189,7 @@ WDL_HASSTRINGS_EXPORT bool WDL_makeSearchFilter(const char *flt, LineParser *lp) if (lp->parse_ex(flt,true,false)) #endif { - lp->set_one_token(flt); // failed parsing search string, search as a single token + if (*flt) lp->set_one_token(flt); // failed parsing search string, search as a single token } return lp->getnumtokens()>0; From 497220287e82fe4088621acba6725df02ec1e76d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 10 Feb 2018 15:33:33 -0500 Subject: [PATCH 017/144] WDL_makeSearchFilter: clear lp on flt=NULL, use WDL_NOT_NORMALLY -- from 3c8a3d70 --- WDL/has_strings.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WDL/has_strings.h b/WDL/has_strings.h index fb0e514a..868ffcd7 100644 --- a/WDL/has_strings.h +++ b/WDL/has_strings.h @@ -181,7 +181,9 @@ WDL_HASSTRINGS_EXPORT bool WDL_hasStrings(const char *name, const LineParser *lp WDL_HASSTRINGS_EXPORT bool WDL_makeSearchFilter(const char *flt, LineParser *lp) { - if (!lp || !flt) return false; + if (WDL_NOT_NORMALLY(!lp)) return false; + + if (WDL_NOT_NORMALLY(!flt)) flt=""; #ifdef WDL_LINEPARSER_HAS_LINEPARSERINT if (lp->parse_ex(flt,true,false,true)) // allow unterminated quotes From 7b09c43c4b6cc118f8c6a0355e7d0f0fa93664f9 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 16 Feb 2018 10:33:35 -0500 Subject: [PATCH 018/144] SWELL: implement WM_SETREDRAW for listviews on macOS -- from a1723f51 --- WDL/swell/swell-types.h | 1 + WDL/swell/swell-wnd.mm | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/WDL/swell/swell-types.h b/WDL/swell/swell-types.h index a1155ae4..8566b14f 100644 --- a/WDL/swell/swell-types.h +++ b/WDL/swell/swell-types.h @@ -906,6 +906,7 @@ __attribute__ ((visibility ("default"))) BOOL WINAPI DllMain(HINSTANCE hInstDLL, #define WM_MOVE 0x0003 #define WM_SIZE 0x0005 #define WM_ACTIVATE 0x0006 +#define WM_SETREDRAW 0x000B // implemented on macOS NSTableViews, maybe elsewhere? #define WM_SETTEXT 0x000C // not implemented on OSX, used internally on Linux #define WM_PAINT 0x000F #define WM_CLOSE 0x0010 diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm index 793b0176..73cf2581 100644 --- a/WDL/swell/swell-wnd.mm +++ b/WDL/swell/swell-wnd.mm @@ -929,6 +929,19 @@ -(LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam return [[self selectedRowIndexes] count]; case LB_DELETESTRING: ListView_DeleteItem((HWND)self, (int)wParam); + return 0; + case WM_SETREDRAW: + if (wParam) + { + if (SWELL_GetOSXVersion() >= 0x1070 && [self respondsToSelector:@selector(endUpdates)]) + [self endUpdates]; + } + else + { + if (SWELL_GetOSXVersion() >= 0x1070 && [self respondsToSelector:@selector(beginUpdates)]) + [self beginUpdates]; + } + return 0; } return 0; From ec01f4a788a5bdc370574e931ad1b1e89637dfea Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 12 Feb 2018 21:08:16 -0500 Subject: [PATCH 019/144] create a native X11 foreign window to host plug-in windows, avoid need for temporary gdk window -- from 10f9b9ba --- WDL/swell/swell-generic-gdk.cpp | 50 +++++++++------------------------ 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index 39178c18..3659e005 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -1802,8 +1802,9 @@ DWORD GetMessagePos() } struct bridgeState { - GdkWindow *w, *delw; + GdkWindow *w; bool lastvis; + bool need_reparent; RECT lastrect; }; static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -1816,7 +1817,6 @@ static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) bridgeState *bs = (bridgeState*)hwnd->m_private_data; hwnd->m_private_data = 0; if (bs->w) gdk_window_destroy(bs->w); - if (bs->delw) gdk_window_destroy(bs->delw); delete bs; } break; @@ -1884,7 +1884,7 @@ static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } } - if (h && (bs->delw || (vis != bs->lastvis) || (vis&&memcmp(&tr,&bs->lastrect,sizeof(RECT))))) + if (h && (bs->need_reparent || (vis != bs->lastvis) || (vis&&memcmp(&tr,&bs->lastrect,sizeof(RECT))))) { if (bs->lastvis && !vis) { @@ -1892,17 +1892,13 @@ static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) bs->lastvis = false; } - if (bs->delw) + if (bs->need_reparent) { gdk_window_reparent(bs->w,h->m_oswindow,tr.left,tr.top); gdk_window_resize(bs->w, tr.right-tr.left,tr.bottom-tr.top); bs->lastrect=tr; - if (bs->delw) - { - gdk_window_destroy(bs->delw); - bs->delw=NULL; - } + bs->need_reparent=false; } else if (memcmp(&tr,&bs->lastrect,sizeof(RECT))) { @@ -1938,37 +1934,19 @@ HWND SWELL_CreateXBridgeWindow(HWND viewpar, void **wref, RECT *r) } bridgeState *bs = new bridgeState; - bs->delw = NULL; + bs->need_reparent=false; bs->lastvis = false; memset(&bs->lastrect,0,sizeof(bs->lastrect)); - GdkWindowAttr attr; if (!ospar) { - memset(&attr,0,sizeof(attr)); - attr.event_mask = GDK_ALL_EVENTS_MASK|GDK_EXPOSURE_MASK; - attr.x = r->left; - attr.y = r->top; - attr.width = r->right-r->left; - attr.height = r->bottom-r->top; - attr.wclass = GDK_INPUT_OUTPUT; - attr.title = (char*)"Temporary window"; - attr.window_type = GDK_WINDOW_TOPLEVEL; - ospar = bs->delw = gdk_window_new(ospar,&attr,GDK_WA_X|GDK_WA_Y); - } - - memset(&attr,0,sizeof(attr)); - attr.event_mask = GDK_ALL_EVENTS_MASK|GDK_EXPOSURE_MASK; - attr.x = r->left; - attr.y = r->top; - attr.width = r->right-r->left; - attr.height = r->bottom-r->top; - attr.wclass = GDK_INPUT_OUTPUT; - attr.title = (char*)"Plug-in Window"; - attr.event_mask = GDK_ALL_EVENTS_MASK|GDK_EXPOSURE_MASK; - attr.window_type = GDK_WINDOW_CHILD; - - bs->w = gdk_window_new(ospar,&attr,GDK_WA_X|GDK_WA_Y); + bs->need_reparent = true; + ospar = gdk_screen_get_root_window(gdk_screen_get_default()); + } + + Display *disp = gdk_x11_display_get_xdisplay(gdk_window_get_display(ospar)); + Window w = XCreateWindow(disp,gdk_x11_window_get_xid(ospar),0,0,r->right-r->left,r->bottom-r->top,0,CopyFromParent, InputOutput, CopyFromParent, 0, NULL); + bs->w = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(),w); hwnd = new HWND__(viewpar,0,r,NULL, true, xbridgeProc); hwnd->m_private_data = (INT_PTR) bs; @@ -1980,7 +1958,7 @@ HWND SWELL_CreateXBridgeWindow(HWND viewpar, void **wref, RECT *r) *wref = (void *) gdk_x11_window_get_xid(bs->w); #endif SetTimer(hwnd,1,100,NULL); - if (!bs->delw) SendMessage(hwnd,WM_SIZE,0,0); + if (!bs->need_reparent) SendMessage(hwnd,WM_SIZE,0,0); } return hwnd; } From b7dd9b5e622d938498cc5ab8839346fb06f60139 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 16 Feb 2018 16:04:50 -0500 Subject: [PATCH 020/144] swell-gdk: XBridge hosting maps child windows -- from 051b434b --- WDL/swell/swell-generic-gdk.cpp | 76 +++++++++++++++++++++++++++------ 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index 3659e005..d7810eec 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -1802,11 +1802,36 @@ DWORD GetMessagePos() } struct bridgeState { + bridgeState(bool needrep, GdkWindow *_w, Window _nw, Display *_disp); + ~bridgeState(); + + GdkWindow *w; + Window native_w; + Display *native_disp; + bool lastvis; bool need_reparent; RECT lastrect; }; + +static WDL_PtrList filter_windows; +bridgeState::~bridgeState() +{ + filter_windows.DeletePtr(this); + if (w) gdk_window_destroy(w); +} +bridgeState::bridgeState(bool needrep, GdkWindow *_w, Window _nw, Display *_disp) +{ + w=_w; + native_w=_nw; + native_disp=_disp; + lastvis=false; + need_reparent=needrep; + memset(&lastrect,0,sizeof(lastrect)); + filter_windows.Add(this); +} + static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) @@ -1816,7 +1841,6 @@ static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { bridgeState *bs = (bridgeState*)hwnd->m_private_data; hwnd->m_private_data = 0; - if (bs->w) gdk_window_destroy(bs->w); delete bs; } break; @@ -1919,6 +1943,27 @@ static LRESULT xbridgeProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) return DefWindowProc(hwnd,uMsg,wParam,lParam); } +static GdkFilterReturn filterCreateShowProc(GdkXEvent *xev, GdkEvent *event, gpointer data) +{ + const XEvent *xevent = (XEvent *)xev; + if (xevent && xevent->type == CreateNotify) + { + for (int x=0;xnative_w == xevent->xany.window && bs->native_disp == xevent->xany.display) + { + //gint w=0,hh=0; + //gdk_window_get_geometry(bs->w,NULL,NULL,&w,&hh); + XMapWindow(bs->native_disp, xevent->xcreatewindow.window); + //XResizeWindow(bs->native_disp, xevent->xcreatewindow.window,w,hh); + return GDK_FILTER_REMOVE; + } + } + } + return GDK_FILTER_CONTINUE; +} + HWND SWELL_CreateXBridgeWindow(HWND viewpar, void **wref, RECT *r) { HWND hwnd = NULL; @@ -1933,32 +1978,35 @@ HWND SWELL_CreateXBridgeWindow(HWND viewpar, void **wref, RECT *r) hpar = hpar->m_parent; } - bridgeState *bs = new bridgeState; - bs->need_reparent=false; - bs->lastvis = false; - memset(&bs->lastrect,0,sizeof(bs->lastrect)); + bool need_reparent=false; if (!ospar) { - bs->need_reparent = true; + need_reparent = true; ospar = gdk_screen_get_root_window(gdk_screen_get_default()); } Display *disp = gdk_x11_display_get_xdisplay(gdk_window_get_display(ospar)); Window w = XCreateWindow(disp,gdk_x11_window_get_xid(ospar),0,0,r->right-r->left,r->bottom-r->top,0,CopyFromParent, InputOutput, CopyFromParent, 0, NULL); - bs->w = gdk_x11_window_foreign_new_for_display(gdk_display_get_default(),w); + GdkWindow *gdkw = w ? gdk_x11_window_foreign_new_for_display(gdk_display_get_default(),w) : NULL; hwnd = new HWND__(viewpar,0,r,NULL, true, xbridgeProc); + bridgeState *bs = gdkw ? new bridgeState(need_reparent,gdkw,w,disp) : NULL; hwnd->m_private_data = (INT_PTR) bs; - if (bs->w) + if (gdkw) { -#if SWELL_TARGET_GDK == 2 - *wref = (void *) GDK_WINDOW_XID(bs->w); -#else - *wref = (void *) gdk_x11_window_get_xid(bs->w); -#endif + *wref = (void *) w; + + XSelectInput(disp, w, StructureNotifyMask | SubstructureNotifyMask); + + static bool filt_add; + if (!filt_add) + { + filt_add=true; + gdk_window_add_filter(NULL, filterCreateShowProc, NULL); + } SetTimer(hwnd,1,100,NULL); - if (!bs->need_reparent) SendMessage(hwnd,WM_SIZE,0,0); + if (!need_reparent) SendMessage(hwnd,WM_SIZE,0,0); } return hwnd; } From e3f6f2a5ad8aff3aaadb52617f7f6e4e4a199958 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 12 Feb 2018 21:33:50 -0500 Subject: [PATCH 021/144] swell-gdk: allow make SWELL_SUPPORT_GTK=1 to initialize GTK, process GTK events -- from ea65933a --- WDL/swell/Makefile | 18 +++++++++++++++--- WDL/swell/swell-generic-gdk.cpp | 16 ++++++++++++++-- WDL/swell/swell-internal.h | 5 +++++ 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index d821f8e1..2b89a4db 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -69,12 +69,24 @@ ifndef NOGDK CFLAGS += -DSWELL_PRELOAD="libgdk-x11-2.0.so.0" endif else - CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gdk-3.0) + ifdef SWELL_SUPPORT_GTK + CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gtk+-3.0) -DSWELL_SUPPORT_GTK + else + CFLAGS += -DSWELL_TARGET_GDK=3 $(shell $(PKG_CONFIG) --cflags gdk-3.0) + endif ifndef PRELOAD_GDK - LINKEXTRA += $(shell $(PKG_CONFIG) --libs gdk-3.0) + ifdef SWELL_SUPPORT_GTK + LINKEXTRA += $(shell $(PKG_CONFIG) --libs gtk+-3.0) + else + LINKEXTRA += $(shell $(PKG_CONFIG) --libs gdk-3.0) + endif else LINKEXTRA += -lX11 -lXi - CFLAGS += -DSWELL_PRELOAD="libgdk-3.so.0" + ifdef SWELL_SUPPORT_GTK + CFLAGS += -DSWELL_PRELOAD="libgtk+-3.so.0" + else + CFLAGS += -DSWELL_PRELOAD="libgdk-3.so.0" + endif endif endif CFLAGS += -DSWELL_LICE_GDI diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index d7810eec..d884af7c 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -288,7 +288,11 @@ void SWELL_initargs(int *argc, char ***argv) _gdk_set_allowed_backends("x11"); #endif +#ifdef SWELL_SUPPORT_GTK + SWELL_gdk_active = gtk_init_check(argc,argv) ? 1 : -1; +#else SWELL_gdk_active = gdk_init_check(argc,argv) ? 1 : -1; +#endif if (SWELL_gdk_active > 0) { char buf[1024]; @@ -1449,6 +1453,9 @@ static void swell_gdkEventHandler(GdkEvent *evt, gpointer data) //printf("msg: %d\n",evt->type); break; } +#ifdef SWELL_SUPPORT_GTK + gtk_main_do_event(evt); +#endif s_cur_evt = oldEvt; } @@ -1456,8 +1463,12 @@ void SWELL_RunEvents() { if (SWELL_gdk_active>0) { -// static GMainLoop *loop; -// if (!loop) loop = g_main_loop_new(NULL,TRUE); +#if 0 && defined(SWELL_SUPPORT_GTK) + // does not seem to be necessary + while (gtk_events_pending()) + gtk_main_iteration(); +#else + #if SWELL_TARGET_GDK == 2 gdk_window_process_all_updates(); #endif @@ -1472,6 +1483,7 @@ void SWELL_RunEvents() gdk_event_free(evt); } } +#endif } } diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h index 864daa4b..28982e0b 100644 --- a/WDL/swell/swell-internal.h +++ b/WDL/swell/swell-internal.h @@ -579,6 +579,11 @@ struct HDC__ { #elif defined(SWELL_TARGET_GDK) + +#ifdef SWELL_SUPPORT_GTK +#include +#endif + #include #include #include From 5518b2be70f286ae963ef5d0430b8425558bac08 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 17 Feb 2018 13:09:27 -0500 Subject: [PATCH 022/144] Remove stray Ctrl+Z -- from 416ce9d3 --- WDL/swell/swell-dlg.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-dlg.mm b/WDL/swell/swell-dlg.mm index 9e848edf..5e87044e 100644 --- a/WDL/swell/swell-dlg.mm +++ b/WDL/swell/swell-dlg.mm @@ -2200,7 +2200,7 @@ void EndDialog(HWND wnd, int ret) [NSApp stopModal]; } - [NSApp abortModal]; // always call this, otherwise if running in runModalForWindow: it can often require another even tto come through before things continue + [NSApp abortModal]; // always call this, otherwise if running in runModalForWindow: it can often require another even tto come through before things continue [nswnd close]; } From 98e8f1dcaf69948f4ce2179d1e3cd393153c2cf3 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 19 Feb 2018 10:51:29 -0500 Subject: [PATCH 023/144] swell-gdk: fix GDK2 compile -- from 272c2d3f --- WDL/swell/swell-generic-gdk.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index d884af7c..c8969f61 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -1999,7 +1999,7 @@ HWND SWELL_CreateXBridgeWindow(HWND viewpar, void **wref, RECT *r) } Display *disp = gdk_x11_display_get_xdisplay(gdk_window_get_display(ospar)); - Window w = XCreateWindow(disp,gdk_x11_window_get_xid(ospar),0,0,r->right-r->left,r->bottom-r->top,0,CopyFromParent, InputOutput, CopyFromParent, 0, NULL); + Window w = XCreateWindow(disp,GDK_WINDOW_XID(ospar),0,0,r->right-r->left,r->bottom-r->top,0,CopyFromParent, InputOutput, CopyFromParent, 0, NULL); GdkWindow *gdkw = w ? gdk_x11_window_foreign_new_for_display(gdk_display_get_default(),w) : NULL; hwnd = new HWND__(viewpar,0,r,NULL, true, xbridgeProc); @@ -2250,11 +2250,10 @@ void SWELL_SetCursor(HCURSOR curs) #endif { Display *disp = gdk_x11_display_get_xdisplay(gdkdisp); -#if SWELL_TARGET_GDK == 2 Window wn = GDK_WINDOW_XID(SWELL_focused_oswindow); +#if SWELL_TARGET_GDK == 2 gint devid=2; // hardcoded default pointing device #else - Window wn = gdk_x11_window_get_xid(SWELL_focused_oswindow); gint devid = gdk_x11_device_get_id(dev); #endif if (disp && wn) From a42899fb3977d8a0c5ab7ced1b7b7221ece4064d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 1 Mar 2018 13:48:03 +0000 Subject: [PATCH 024/144] eel_lice: extend setup_frame for non-hwnd-based drawing -- from 0ede8e17 --- WDL/eel2/eel_lice.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index c217207d..922c0699 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -257,7 +257,7 @@ class eel_lice_state NSEEL_VMCTX m_vmref; void *m_user_ctx; - int setup_frame(HWND hwnd, RECT r); + int setup_frame(HWND hwnd, RECT r, int _mouse_x=0, int _mouse_y=0); // mouse_x/y used only if hwnd is NULL void gfx_lineto(EEL_F xpos, EEL_F ypos, EEL_F aaflag); void gfx_rectto(EEL_F xpos, EEL_F ypos); @@ -1693,20 +1693,23 @@ void eel_lice_state::gfx_drawnumber(EEL_F n, EEL_F ndigits) getCurColor(),getCurMode(),(float)*m_gfx_a,DT_NOCLIP,NULL,NULL); } -int eel_lice_state::setup_frame(HWND hwnd, RECT r) +int eel_lice_state::setup_frame(HWND hwnd, RECT r, int _mouse_x, int _mouse_y) { int use_w = r.right - r.left; int use_h = r.bottom - r.top; - POINT pt; - GetCursorPos(&pt); - ScreenToClient(hwnd,&pt); + POINT pt = { _mouse_x, _mouse_y }; + if (hwnd) + { + GetCursorPos(&pt); + ScreenToClient(hwnd,&pt); + } *m_mouse_x=pt.x-r.left; *m_mouse_y=pt.y-r.top; if (*m_gfx_ext_retina > 0.0) { #ifdef __APPLE__ - *m_gfx_ext_retina = SWELL_IsRetinaHWND(hwnd) ? 2.0 : 1.0; + *m_gfx_ext_retina = (hwnd && SWELL_IsRetinaHWND(hwnd)) ? 2.0 : 1.0; if (*m_gfx_ext_retina > 1.0) { *m_mouse_x *= 2.0; @@ -1771,7 +1774,7 @@ int eel_lice_state::setup_frame(HWND hwnd, RECT r) if (GetAsyncKeyState(VK_RBUTTON)&0x8000) vflags|=swap?1:2; if (GetAsyncKeyState(VK_MBUTTON)&0x8000) vflags|=64; } - if (m_has_cap || (m_has_had_getch && GetFocus()==hwnd)) + if (m_has_cap || (m_has_had_getch && hwnd && GetFocus()==hwnd)) { if (GetAsyncKeyState(VK_CONTROL)&0x8000) vflags|=4; if (GetAsyncKeyState(VK_SHIFT)&0x8000) vflags|=8; From 107d8291049e55adf4e861802961ea8ed3a4f957 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 3 Mar 2018 14:48:08 +0000 Subject: [PATCH 025/144] swell-gdi-lice: clip GetDC() calls to parent windows -- from 0965faa5 --- WDL/swell/swell-gdi-lice.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp index 706bc8c3..6032aff9 100644 --- a/WDL/swell/swell-gdi-lice.cpp +++ b/WDL/swell/swell-gdi-lice.cpp @@ -1320,6 +1320,7 @@ HDC SWELL_internalGetWindowDC(HWND h, bool calcsize_on_first) bool vis=true; HWND starth = h; + int ltrim=0, ttrim=0, rtrim=0, btrim=0; for (;;) { if ((calcsize_on_first || h!=starth) && h->m_wndproc) @@ -1346,22 +1347,32 @@ HDC SWELL_internalGetWindowDC(HWND h, bool calcsize_on_first) xoffs += h->m_position.left; yoffs += h->m_position.top; + + ltrim = wdl_max(ltrim, -xoffs); + ttrim = wdl_max(ttrim, -yoffs); + rtrim = wdl_max(rtrim, xoffs+wndw - h->m_position.right); + btrim = wdl_max(btrim, yoffs+wndh - h->m_position.bottom); + h = h->m_parent; } swell_gdpLocalContext *p = (swell_gdpLocalContext*)SWELL_GDP_CTX_NEW(); - p->clipr.left=p->clipr.right=xoffs; - p->clipr.top=p->clipr.bottom=yoffs; + p->clipr.left=p->clipr.right=xoffs + ltrim; + p->clipr.top=p->clipr.bottom=yoffs + ttrim; if (h->m_backingstore && vis) { - p->ctx.surface=new LICE_SubBitmap(h->m_backingstore,xoffs,yoffs,wndw,wndh); + p->ctx.surface=new LICE_SubBitmap(h->m_backingstore, + xoffs+ltrim,yoffs+ttrim, + wndw-ltrim-rtrim,wndh-ttrim-btrim); p->clipr.right += p->ctx.surface->getWidth(); p->clipr.bottom += p->ctx.surface->getHeight(); } if (xoffs<0) p->ctx.surface_offs.x = xoffs; if (yoffs<0) p->ctx.surface_offs.y = yoffs; + p->ctx.surface_offs.x -= ltrim; + p->ctx.surface_offs.y -= ttrim; p->ctx.curfont = starth->m_font; // todo: other GDI defaults? From 070093669aee56cf8a3d641630886aab59e63760 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 7 Mar 2018 15:31:13 -0500 Subject: [PATCH 026/144] curses_win32: cleanup character drawing code -- from f24840a0 --- WDL/win32_curses/curses_win32.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/WDL/win32_curses/curses_win32.cpp b/WDL/win32_curses/curses_win32.cpp index b69ed81d..a918830d 100644 --- a/WDL/win32_curses/curses_win32.cpp +++ b/WDL/win32_curses/curses_win32.cpp @@ -604,12 +604,17 @@ LRESULT CALLBACK cursesWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lP { FillRect(hdc,&tr,br); } - char tmp[16]={c,0}; + char tmp[16]; if (c >= 128) { WDL_MakeUTFChar(tmp,c,sizeof(tmp)); } - DrawText(hdc,isNotBlank ? tmp : " ",-1,&tr,DT_LEFT|DT_TOP|DT_NOPREFIX|DT_NOCLIP); + else + { + tmp[0]=isNotBlank ? (char)c : ' '; + tmp[1]=0; + } + DrawText(hdc,tmp,-1,&tr,DT_LEFT|DT_TOP|DT_NOPREFIX|DT_NOCLIP); #endif if (isCursor && ctx->cursor_type != WIN32_CURSES_CURSOR_TYPE_BLOCK) From b0d9ef2a70dc15f4a508859c4de4e1a1de8efd86 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 11 Mar 2018 15:27:45 -0400 Subject: [PATCH 027/144] eel2: allow validating function names at runtime (for implementing safe modes) -- from 2c2e2e8f --- WDL/eel2/ns-eel-int.h | 2 ++ WDL/eel2/ns-eel.h | 3 +++ WDL/eel2/nseel-compiler.c | 26 ++++++++++++++++++++++++-- 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/WDL/eel2/ns-eel-int.h b/WDL/eel2/ns-eel-int.h index 19ad4172..9f74f7b1 100644 --- a/WDL/eel2/ns-eel-int.h +++ b/WDL/eel2/ns-eel-int.h @@ -164,6 +164,8 @@ typedef struct { typedef struct _compileContext { eel_function_table *registered_func_tab; + const char *(*func_check)(const char *fn_name, void *user); // return error message if not permitted + void *func_check_user; EEL_F **varTable_Values; char ***varTable_Names; diff --git a/WDL/eel2/ns-eel.h b/WDL/eel2/ns-eel.h index 56050833..8b125c8f 100644 --- a/WDL/eel2/ns-eel.h +++ b/WDL/eel2/ns-eel.h @@ -125,6 +125,9 @@ void NSEEL_VM_free(NSEEL_VMCTX ctx); // free when done with a VM and ALL of its void NSEEL_VM_SetFunctionTable(NSEEL_VMCTX, eel_function_table *tab); // use NULL to use default (global) table +// validateFunc can return error message if not permitted +void NSEEL_VM_SetFunctionValidator(NSEEL_VMCTX, const char * (*validateFunc)(const char *fn_name, void *user), void *user); + void NSEEL_VM_remove_unused_vars(NSEEL_VMCTX _ctx); void NSEEL_VM_clear_var_refcnts(NSEEL_VMCTX _ctx); void NSEEL_VM_remove_all_nonreg_vars(NSEEL_VMCTX _ctx); diff --git a/WDL/eel2/nseel-compiler.c b/WDL/eel2/nseel-compiler.c index 85dd3d0b..6a5421aa 100644 --- a/WDL/eel2/nseel-compiler.c +++ b/WDL/eel2/nseel-compiler.c @@ -841,6 +841,7 @@ opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int p unsigned char match_parmcnt_pos=0; char *sname = (char *)rec->relname; int is_string_prefix = parmcnt < 0 && sname[0] == '#'; + const char *prevent_function_calls = NULL; if (errOut) *errOut = 0; @@ -961,17 +962,20 @@ opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int p return rec; } + + if (ctx->func_check) + prevent_function_calls = ctx->func_check(sname,ctx->func_check_user); ////////// function mode // first off, while() and loop() are special and can't be overridden // - if (parmcnt == 1 && !stricmp("while",sname)) + if (parmcnt == 1 && !stricmp("while",sname) && !prevent_function_calls) { rec->opcodeType = OPCODETYPE_FUNC1; rec->fntype = FN_WHILE; return rec; } - if (parmcnt == 2 && !stricmp("loop",sname)) + if (parmcnt == 2 && !stricmp("loop",sname) && !prevent_function_calls) { rec->opcodeType = OPCODETYPE_FUNC2; rec->fntype = FN_LOOP; @@ -1081,6 +1085,14 @@ opcodeRec *nseel_resolve_named_symbol(compileContext *ctx, opcodeRec *rec, int p } } + if (prevent_function_calls) + { + if (ctx->last_error_string[0]) lstrcatn(ctx->last_error_string, ", ", sizeof(ctx->last_error_string)); + snprintf_append(ctx->last_error_string,sizeof(ctx->last_error_string),"'%.30s': %s",sname, prevent_function_calls); + if (errOut) *errOut = 0; + return NULL; + } + #ifdef NSEEL_EEL1_COMPAT_MODE if (!stricmp(sname,"assign")) { @@ -5104,6 +5116,16 @@ int NSEEL_VM_setramsize(NSEEL_VMCTX _ctx, int maxent) return ctx->ram_state.maxblocks * NSEEL_RAM_ITEMSPERBLOCK; } +void NSEEL_VM_SetFunctionValidator(NSEEL_VMCTX _ctx, const char * (*validateFunc)(const char *fn_name, void *user), void *user) +{ + if (_ctx) + { + compileContext *ctx = (compileContext *)_ctx; + ctx->func_check = validateFunc; + ctx->func_check_user = user; + } +} + void NSEEL_VM_SetFunctionTable(NSEEL_VMCTX _ctx, eel_function_table *tab) { if (_ctx) From 05414124005aae1d5de19f62b2bc95a6662b94c2 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 13 Mar 2018 11:15:02 -0400 Subject: [PATCH 028/144] swell: UnionRect() with empty rectangle returns other rectangle -- from c27fd888 --- WDL/swell/swell.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 69f3dd98..e6a57cc0 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -592,10 +592,21 @@ int WinIntersectRect(RECT *out, const RECT *in1, const RECT *in2) } void WinUnionRect(RECT *out, const RECT *in1, const RECT *in2) { - out->left = wdl_min(in1->left,in2->left); - out->top = wdl_min(in1->top,in2->top); - out->right=wdl_max(in1->right,in2->right); - out->bottom=wdl_max(in1->bottom,in2->bottom); + if (in1->left == in1->right && in1->top == in1->bottom) + { + *out = *in2; + } + else if (in2->left == in2->right && in2->top == in2->bottom) + { + *out = *in1; + } + else + { + out->left = wdl_min(in1->left,in2->left); + out->top = wdl_min(in1->top,in2->top); + out->right=wdl_max(in1->right,in2->right); + out->bottom=wdl_max(in1->bottom,in2->bottom); + } } From d4a4bb317ae6ffb184ee6073e85466def6c45943 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 14 Mar 2018 11:53:44 -0400 Subject: [PATCH 029/144] swell-cocoa: call noteNumberOfRowsChanged from ListView_SetItemCount() -- from b0d22f3d --- WDL/swell/swell-wnd.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm index 73cf2581..36d31201 100644 --- a/WDL/swell/swell-wnd.mm +++ b/WDL/swell/swell-wnd.mm @@ -4632,6 +4632,7 @@ void ListView_SetItemCount(HWND h, int cnt) if (!tv->m_lbMode && (tv->style & LVS_OWNERDATA)) { tv->ownermode_cnt=cnt; + [tv noteNumberOfRowsChanged]; } } From b582f9d84adb7bf4b62a388b08bdd7bb41da50f1 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 15 Mar 2018 07:55:52 -0400 Subject: [PATCH 030/144] swell: add WM_COPYDATA definition -- from fc1ad620 --- WDL/swell/swell-types.h | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-types.h b/WDL/swell/swell-types.h index 8566b14f..04d59894 100644 --- a/WDL/swell/swell-types.h +++ b/WDL/swell/swell-types.h @@ -920,8 +920,8 @@ __attribute__ ((visibility ("default"))) BOOL WINAPI DllMain(HINSTANCE hInstDLL, #define WM_SETFONT 0x0030 #define WM_GETFONT 0x0031 #define WM_GETOBJECT 0x003D // implemented differently than win32 -- see virtwnd/virtwnd-nsaccessibility.mm +#define WM_COPYDATA 0x004A #define WM_NOTIFY 0x004E - #define WM_CONTEXTMENU 0x007B #define WM_STYLECHANGED 0x007D #define WM_DISPLAYCHANGE 0x007E @@ -976,7 +976,6 @@ __attribute__ ((visibility ("default"))) BOOL WINAPI DllMain(HINSTANCE hInstDLL, #define WM_DROPFILES 0x0233 #define WM_USER 0x0400 - #define HTCAPTION 2 #define HTBOTTOMRIGHT 17 @@ -1370,5 +1369,12 @@ typedef struct _ICONINFO HBITMAP hbmColor; } ICONINFO, *PICONINFO; +typedef struct _COPYDATASTRUCT +{ + ULONG_PTR dwData; + DWORD cbData; + PVOID lpData; +} COPYDATASTRUCT, *PCOPYDATASTRUCT; + #endif //_WDL_SWELL_H_TYPES_DEFINED_ From 93fecd4c5f2b2a8fa8b6bb4e7e6e65cb389228b5 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 16 Mar 2018 11:42:48 -0400 Subject: [PATCH 031/144] swell: mac_resgen.php can accept --quiet which will not output when skipping all processing -- from 67834bdd --- WDL/swell/mac_resgen.php | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/WDL/swell/mac_resgen.php b/WDL/swell/mac_resgen.php index c3dc6254..36eb0da7 100755 --- a/WDL/swell/mac_resgen.php +++ b/WDL/swell/mac_resgen.php @@ -293,16 +293,21 @@ function swell_rc2cpp_menu($fp) // returns array with ["data"] and optionally [" $proc=0; $skipped=0; $err=0; +$quiet=0; for (; $x < count($argv); $x ++) { $srcfn = $argv[$x]; + if ($srcfn == "--quiet") + { + $quiet = 1; + continue; + } if (!stristr($srcfn,".rc") || !($fp = @fopen($srcfn,"r"))) { $err++; echo "$srcfn: not valid or not found!\n"; continue; } - echo "$srcfn: "; $ofnmenu = $srcfn . "_mac_menu"; $ofndlg = $srcfn . "_mac_dlg"; @@ -312,7 +317,7 @@ function swell_rc2cpp_menu($fp) // returns array with ["data"] and optionally [" if ($res["error"] != "" || $res2["error"] != "") { $err++; - echo "error"; + echo "$srcfn: error"; if ($res["error"] != "") echo " dialog: " . $res["error"]; if ($res2["error"] != "") echo " menu: " . $res2["error"]; echo "\n"; @@ -331,12 +336,18 @@ function swell_rc2cpp_menu($fp) // returns array with ["data"] and optionally [" if (!file_put_contents($ofnmenu,$res2["data"],LOCK_EX)) { echo "error writing $ofnmenu\n"; $err++; } } + if ($f != "") + { + $proc++; + } + else + { + $skipped++; + $f = "skipped"; + } - if ($f) echo "$f\n"; - else echo "skipped\n"; - if ($f != "") $proc++; - else $skipped++; + if (!$quiet) echo "$srcfn: $f\n"; } -echo "processed $proc, skipped $skipped, error $err\n"; +if (!$quiet || $proc || $err) echo "processed $proc, skipped $skipped, error $err\n"; ?> From 06e27fc8b0546ce4e96320ce55ade92197b0f66c Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 20 Mar 2018 10:11:23 -0400 Subject: [PATCH 032/144] swell-gdk: ignore various modifier keys -- from bd4d828c --- WDL/swell/swell-generic-gdk.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index c8969f61..a87eadd4 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -960,7 +960,10 @@ static void OnKeyEvent(GdkEventKey *k) } else { - if (kv >= DEF_GKY(Shift_L)) + if (kv >= DEF_GKY(Shift_L) || + (kv >= DEF_GKY(ISO_Lock) && + kv <= DEF_GKY(ISO_Last_Group_Lock)) + ) { if (kv == DEF_GKY(Shift_L) || kv == DEF_GKY(Shift_R)) kv = VK_SHIFT; else if (kv == DEF_GKY(Control_L) || kv == DEF_GKY(Control_R)) kv = VK_CONTROL; From 4430af0dee9c6e594d8df74d84ebe027e3222e67 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 22 Mar 2018 17:08:33 -0400 Subject: [PATCH 033/144] has_strings: ignore unquoted uppercase AND keywords -- from 73831eac --- WDL/has_strings.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/WDL/has_strings.h b/WDL/has_strings.h index 868ffcd7..503c9568 100644 --- a/WDL/has_strings.h +++ b/WDL/has_strings.h @@ -33,10 +33,9 @@ WDL_HASSTRINGS_EXPORT bool WDL_hasStrings(const char *name, const LineParser *lp int stacktop = 0; stack[0]=0; - int x,ln; const int strlen_name = (int)strlen(name); char matched_local=-1; // -1 = first eval for scope, 0=did not pass scope, 1=OK, 2=ignore rest of scope - for (x = 0; x < ntok; x ++) + for (int x = 0; x < ntok; x ++) { const char *n=lp->gettoken_str(x); @@ -74,10 +73,15 @@ WDL_HASSTRINGS_EXPORT bool WDL_hasStrings(const char *name, const LineParser *lp } else if (matched_local&1) // matches 1, -1 { + int ln; if (!strcmp(n,"NOT")) { stack[stacktop]^=1; } + else if (!strcmp(n,"AND") && !lp->gettoken_quotingchar(x)) + { + // ignore unquoted uppercase AND + } else if ((ln=(int)strlen(n))>0) { int lt=strlen_name; From 8ef34f2fb800215d9a22165680ffa0f949c98b03 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 22 Mar 2018 17:28:20 -0400 Subject: [PATCH 034/144] swell-generic: use execvp() for SWELL_CreateProcess() -- from e0868cda --- WDL/swell/swell-misc-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-misc-generic.cpp b/WDL/swell/swell-misc-generic.cpp index 42a3b230..fc77cba7 100644 --- a/WDL/swell/swell-misc-generic.cpp +++ b/WDL/swell/swell-misc-generic.cpp @@ -38,7 +38,7 @@ HANDLE SWELL_CreateProcess(const char *exe, int nparams, const char **params) char **pp = (char **)calloc(nparams+2,sizeof(char*)); pp[0] = strdup(exe); for (int x=0;x Date: Sun, 25 Mar 2018 12:25:19 -0400 Subject: [PATCH 035/144] - linux: use PTHREAD_PRIO_INHERIT for mutexes WDL_Mutex: use PTHREAD_PRIO_INHERIT for mutexes on linux (test) -- from 80c9c2d4 --- WDL/mutex.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WDL/mutex.h b/WDL/mutex.h index 0af8e08b..dbfec113 100644 --- a/WDL/mutex.h +++ b/WDL/mutex.h @@ -68,13 +68,17 @@ class WDL_Mutex { InitializeCriticalSection(&m_cs); #elif defined( WDL_MAC_USE_CARBON_CRITSEC) MPCreateCriticalRegion(&m_cr); -#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) +#elif defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER) && !defined(__linux__) const pthread_mutex_t tmp = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; m_mutex = tmp; #else pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE); +#ifdef __linux__ + // todo: macos too? + pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_INHERIT); +#endif pthread_mutex_init(&m_mutex,&attr); pthread_mutexattr_destroy(&attr); #endif From b6addf2c19d2b31a529deaaf0fef5f8d42caad8c Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 25 Mar 2018 18:37:46 -0400 Subject: [PATCH 036/144] WDL_FileRead: better error handling when calculating file sizes -- from 8559265d --- WDL/fileread.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WDL/fileread.h b/WDL/fileread.h index c185e96a..8e6fbc42 100644 --- a/WDL/fileread.h +++ b/WDL/fileread.h @@ -204,6 +204,7 @@ class WDL_FileRead__ReadEnt DWORD h=0; DWORD l=GetFileSize(m_fh,&h); m_fsize=(((WDL_FILEREAD_POSTYPE)h)<<32)|l; + if (m_fsize<0 || (l == INVALID_FILE_SIZE && GetLastError() != NO_ERROR)) m_fsize=0; if (!h && l < mmap_maxsize && m_async<=0) { @@ -271,6 +272,7 @@ class WDL_FileRead__ReadEnt #endif m_fsize=lseek(m_filedes,0,SEEK_END); lseek(m_filedes,0,SEEK_SET); + if (m_fsize<0) m_fsize=0; if (m_fsize < mmap_maxsize) { From 1a8db5d23d8fbd577fed00e0562ac5795cf91f7f Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 30 Mar 2018 09:21:46 -0400 Subject: [PATCH 037/144] - linux: use clock_gettime(CLOCK_MONOTONIC) for various timings, use prio_inherit for event mutexes -- from 9d93b439 --- WDL/swell/swell.cpp | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index e6a57cc0..da72b729 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -64,9 +64,16 @@ void Sleep(int ms) DWORD GetTickCount() { +#ifdef __APPLE__ + // could switch to mach_getabsolutetime() maybe struct timeval tm={0,}; gettimeofday(&tm,NULL); return (DWORD) (tm.tv_sec*1000 + tm.tv_usec/1000); +#else + struct timespec ts={0,}; + clock_gettime(CLOCK_MONOTONIC,&ts); + return (DWORD) (ts.tv_sec*1000 + ts.tv_nsec/1000000); +#endif } @@ -338,11 +345,10 @@ DWORD WaitForSingleObject(HANDLE hand, DWORD msTO) break; } #else - struct timeval tm={0,}; - gettimeofday(&tm,NULL); struct timespec ts; - ts.tv_sec = msTO/1000 + tm.tv_sec; - ts.tv_nsec = (tm.tv_usec + (msTO%1000)*1000) * 1000; + clock_gettime(CLOCK_MONOTONIC,&ts); + ts.tv_sec += msTO/1000; + ts.tv_nsec += (msTO%1000)*1000000; if (ts.tv_nsec>=1000000000) { int n = ts.tv_nsec/1000000000; @@ -401,8 +407,23 @@ HANDLE CreateEvent(void *SA, BOOL manualReset, BOOL initialSig, const char *igno buf->isSignal = !!initialSig; buf->isManualReset = !!manualReset; - pthread_mutex_init(&buf->mutex,NULL); + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); +#ifdef __linux__ + pthread_mutexattr_setprotocol(&attr,PTHREAD_PRIO_INHERIT); +#endif + pthread_mutex_init(&buf->mutex,&attr); + pthread_mutexattr_destroy(&attr); + +#ifndef __APPLE__ + pthread_condattr_t cattr; + pthread_condattr_init(&cattr); + pthread_condattr_setclock(&cattr,CLOCK_MONOTONIC); + pthread_cond_init(&buf->cond,&cattr); + pthread_condattr_destroy(&cattr); +#else pthread_cond_init(&buf->cond,NULL); +#endif return (HANDLE)buf; } From 81a24a2f4de84fac4f3ea9d1ce152099011b828b Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 1 Apr 2018 18:41:04 -0400 Subject: [PATCH 038/144] wdlstring: fix possible sign-overflow warning -- from 8835e7f4 --- WDL/wdlstring.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WDL/wdlstring.h b/WDL/wdlstring.h index aefdbbc8..f0cdc1b3 100644 --- a/WDL/wdlstring.h +++ b/WDL/wdlstring.h @@ -368,7 +368,8 @@ class WDL_String { const int oldsz = m_hb.GetSize(); const int newsz=offs+len+trailkeep+1; - if (newsz-oldsz > 0) + const int growamt = newsz-oldsz; + if (growamt > 0) { const char *oldb = (const char *)m_hb.Get(); const char *newb = (const char *)m_hb.Resize(newsz,false); // resize up if necessary @@ -385,7 +386,7 @@ class WDL_String newbuf[newsz-1]=0; // resize down if necessary - if (newsz < oldsz) m_hb.Resize(newsz,false); + if (growamt < 0) m_hb.Resize(newsz,false); } } } From a75a0a6e7e7bf28e7a895c9ea1ca46fb00149b78 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 1 Apr 2018 18:43:14 -0400 Subject: [PATCH 039/144] giflib: fix some compiler warnings -- from 6029abc2 --- WDL/giflib/config.h | 5 ++++- WDL/giflib/dgif_lib.c | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/WDL/giflib/config.h b/WDL/giflib/config.h index 23e7dbf5..ba731f41 100644 --- a/WDL/giflib/config.h +++ b/WDL/giflib/config.h @@ -6,6 +6,9 @@ #define _OPEN_BINARY #else typedef unsigned int UINT32; +#include +#include +#include #endif #include -#endif \ No newline at end of file +#endif diff --git a/WDL/giflib/dgif_lib.c b/WDL/giflib/dgif_lib.c index 73e092ce..0fd062ef 100644 --- a/WDL/giflib/dgif_lib.c +++ b/WDL/giflib/dgif_lib.c @@ -138,7 +138,7 @@ DGifOpenFileHandle(int FileHandle) { /* The GIF Version number is ignored at this time. Maybe we should do * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; - if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { + if (strncmp(GIF_STAMP, (char*)Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; fclose(f); free((char *)Private); @@ -205,7 +205,7 @@ DGifOpen(void *userData, /* The GIF Version number is ignored at this time. Maybe we should do * something more useful with it. */ Buf[GIF_STAMP_LEN] = 0; - if (strncmp(GIF_STAMP, Buf, GIF_VERSION_POS) != 0) { + if (strncmp(GIF_STAMP, (char*)Buf, GIF_VERSION_POS) != 0) { _GifError = D_GIF_ERR_NOT_GIF_FILE; free((char *)Private); free((char *)GifFile); From 9a093182620b5431c3a8cccfae505bb83d95d6f6 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 1 Apr 2018 19:50:07 -0400 Subject: [PATCH 040/144] zlib: fix clang warning for (usually unused) inflateMark() -- from 4101f7c2 --- WDL/zlib/inflate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/zlib/inflate.c b/WDL/zlib/inflate.c index 870f89bb..e72c1ad2 100644 --- a/WDL/zlib/inflate.c +++ b/WDL/zlib/inflate.c @@ -1504,7 +1504,7 @@ z_streamp strm; { struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + if (strm == Z_NULL || strm->state == Z_NULL) return -65536; state = (struct inflate_state FAR *)strm->state; return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : From b89071e5f0b600f6b41774fd304d8f05ac98a323 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 1 Apr 2018 21:49:45 -0400 Subject: [PATCH 041/144] SWELL: fix a couple of warnings -- from 1a478c65, 2765aecb --- WDL/swell/swell-internal.h | 1 + WDL/swell/swell-wnd-generic.cpp | 2 +- WDL/swell/swell-wnd.mm | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h index 28982e0b..8a770c4c 100644 --- a/WDL/swell/swell-internal.h +++ b/WDL/swell/swell-internal.h @@ -331,6 +331,7 @@ typedef struct WindowPropRec -(void *)swellGetProp:(const char *)name wantRemove:(BOOL)rem; -(int)swellSetProp:(const char *)name value:(void *)val ; -(NSOpenGLContext *)swellGetGLContext; +- (void) setEnabledSwellNoFocus; // NSAccessibility diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 266f335f..5d2bec2f 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6831,7 +6831,7 @@ LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (hwnd->m_font) return (LRESULT) hwnd->m_font; #ifdef SWELL_FREETYPE { - HFONT SWELL_GetDefaultFont(); + HFONT SWELL_GetDefaultFont(void); return (LRESULT)SWELL_GetDefaultFont(); } #endif diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm index 36d31201..e5c0227a 100644 --- a/WDL/swell/swell-wnd.mm +++ b/WDL/swell/swell-wnd.mm @@ -1688,7 +1688,7 @@ void EnableWindow(HWND hwnd, int enable) if (bla && [bla respondsToSelector:@selector(setEnabled:)]) { if (enable == -1000 && [bla respondsToSelector:@selector(setEnabledSwellNoFocus)]) - [bla setEnabledSwellNoFocus]; + [(SWELL_hwndChild *)bla setEnabledSwellNoFocus]; else [bla setEnabled:(enable?YES:NO)]; if ([bla isKindOfClass:[SWELL_TextField class]]) From 3490deaec8b846e05c3a68b71509a84bb4d76c6e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 1 Apr 2018 21:44:18 -0400 Subject: [PATCH 042/144] EEL2: fix warning when macOS already defines EEL_USE_MPROTECT -- from a28a2c81 --- WDL/eel2/nseel-compiler.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WDL/eel2/nseel-compiler.c b/WDL/eel2/nseel-compiler.c index 6a5421aa..01c62c35 100644 --- a/WDL/eel2/nseel-compiler.c +++ b/WDL/eel2/nseel-compiler.c @@ -41,7 +41,9 @@ #include #if defined(__LP64__) || defined(MAC_OS_X_VERSION_10_6) // using 10.6+ SDK, force mprotect use - #define EEL_USE_MPROTECT + #ifndef EEL_USE_MPROTECT + #define EEL_USE_MPROTECT + #endif #endif #endif From 2fd39aa7d1683f1679685462b1a69998246e2a0e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 09:40:56 -0400 Subject: [PATCH 043/144] WDL_PtrList: simplify bounds-checking of WDL_PtrList::Get() -- from 0c3c5274 --- WDL/ptrlist.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/ptrlist.h b/WDL/ptrlist.h index 154e0420..9f867ccf 100644 --- a/WDL/ptrlist.h +++ b/WDL/ptrlist.h @@ -51,7 +51,7 @@ template class WDL_PtrList PTRTYPE *Get(INT_PTR index) const { PTRTYPE **list = (PTRTYPE**)m_hb.Get(); - if (list && index >= 0 && index < (INT_PTR)(m_hb.GetSize()/sizeof(PTRTYPE *))) return list[index]; + if (list && (UINT_PTR)index < (UINT_PTR)(m_hb.GetSize()/sizeof(PTRTYPE *))) return list[index]; return NULL; } From 93c7d527ee0aa2296ede43dbf77b0fea8bb118b3 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 13:46:20 -0400 Subject: [PATCH 044/144] Makefile updates to use clang/clang++ if CLANG defined, fixed static compile -- from aff582f4 --- WDL/swell/Makefile | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index 2b89a4db..a17d1b21 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -13,10 +13,16 @@ CFLAGS = -pipe -fvisibility=hidden -fno-math-errno -fPIC -DPIC -Wall -Wshadow -W ifeq ($(UNAME_S),Darwin) CFLAGS += -Wno-unused-private-field -DSWELL_FORCE_GENERIC DLL_EXT=.dylib + CLANG=1 else DLL_EXT=.so endif +ifdef CLANG + CC = clang + CXX = clang++ +endif + ifndef ALLOW_WARNINGS CFLAGS += -Werror endif @@ -33,7 +39,7 @@ ifdef DEBUG CFLAGS += -O0 -g -D_DEBUG else CFLAGS += -O2 -DNDEBUG - ifneq ($(UNAME_S),Darwin) + ifndef CLANG CFLAGS += -s endif endif From 80de98894ba201dfcaaeeb9ff7175a4af73b4753 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 14:29:18 -0400 Subject: [PATCH 045/144] SWELL: update generic API in order to not require global symbols (allows clang/ICC linux builds) -- from c26f619d --- WDL/swell/Makefile | 2 + WDL/swell/swell-appstub-generic.cpp | 29 ++++++++++++++ WDL/swell/swell-modstub-generic.cpp | 62 +++++++++++++++++------------ WDL/swell/swell.cpp | 18 +++++++-- 4 files changed, 82 insertions(+), 29 deletions(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index a17d1b21..3d510cf4 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -10,6 +10,8 @@ PKG_CONFIG = pkg-config CFLAGS = -pipe -fvisibility=hidden -fno-math-errno -fPIC -DPIC -Wall -Wshadow -Wno-unused-function -Wno-multichar -Wno-unused-result +CFLAGS += -DSWELL_MAKING_DYLIB + ifeq ($(UNAME_S),Darwin) CFLAGS += -Wno-unused-private-field -DSWELL_FORCE_GENERIC DLL_EXT=.dylib diff --git a/WDL/swell/swell-appstub-generic.cpp b/WDL/swell/swell-appstub-generic.cpp index d2a2ed75..78d20f18 100644 --- a/WDL/swell/swell-appstub-generic.cpp +++ b/WDL/swell/swell-appstub-generic.cpp @@ -45,6 +45,7 @@ static int compfunc(const void *a, const void *b) } extern "C" { + __attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name) { if (!name) return (void *)0x100; // version @@ -59,6 +60,34 @@ __attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name if (res) return res->func; return NULL; } + +}; + +#ifdef SWELL_MAKING_DYLIB +static INT_PTR (*s_AppMain)(int msg, INT_PTR parm1, INT_PTR parm2); +INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) +{ + // remove this code in 2019 or later + static char chk; + if (!s_AppMain && !chk) + { + chk=1; + *(void **)&s_AppMain = dlsym(NULL,"SWELLAppMain"); + printf("swell-dylib: used legacy SWELLAppMain get to get %p\n",s_AppMain); + } + // end temp code + + if (s_AppMain) return s_AppMain(msg,parm1,parm2); + return 0; +} + +extern "C" { +__attribute__ ((visibility ("default"))) void SWELL_set_app_main(INT_PTR (*AppMain)(int msg, INT_PTR parm1, INT_PTR parm2)) +{ + s_AppMain = AppMain; +} }; #endif + +#endif diff --git a/WDL/swell/swell-modstub-generic.cpp b/WDL/swell/swell-modstub-generic.cpp index e1bb9f13..e063c526 100644 --- a/WDL/swell/swell-modstub-generic.cpp +++ b/WDL/swell/swell-modstub-generic.cpp @@ -50,16 +50,32 @@ static struct static int dummyFunc() { return 0; } +static int doinit(void *(*GetFunc)(const char *name)) +{ + int errcnt=0; + for (int x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++) + { + *api_tab[x].func=GetFunc(api_tab[x].name); + if (!*api_tab[x].func) + { + printf("SWELL API not found: %s\n",api_tab[x].name); + errcnt++; + *api_tab[x].func = (void*)&dummyFunc; + } + } + return errcnt; +} + #ifdef SWELL_LOAD_SWELL_DYLIB + static void *(*__loaded_getfunc)(const char *name)=NULL; -#endif + class SwellAPPInitializer { public: SwellAPPInitializer() { void *(*SWELLAPI_GetFunc)(const char *name)=NULL; -#ifdef SWELL_LOAD_SWELL_DYLIB char fn[4096]; const int nSize=sizeof(fn)-64; char lnk[64]; @@ -83,30 +99,16 @@ class SwellAPPInitializer if (preload_fn && *preload_fn) dlopen(preload_fn,RTLD_LAZY|RTLD_GLOBAL); -#else - void *tmp = dlopen(NULL,RTLD_LAZY); -#endif - - if (tmp) *(void **)&SWELLAPI_GetFunc = dlsym(tmp,"SWELLAPI_GetFunc"); - //printf("tmp=%08x, SWELLAPI_GetFunc=%08x\n",tmp,SWELLAPI_GetFunc); - - if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)!=(void*)0x100) SWELLAPI_GetFunc=0; + *(void **)&SWELLAPI_GetFunc = dlsym(tmp,"SWELLAPI_GetFunc"); -#ifdef SWELL_LOAD_SWELL_DYLIB - __loaded_getfunc = SWELLAPI_GetFunc; -#endif - int x; - for (x = 0; x < sizeof(api_tab)/sizeof(api_tab[0]); x ++) + if (SWELLAPI_GetFunc && SWELLAPI_GetFunc(NULL)==(void*)0x100) { - *api_tab[x].func=SWELLAPI_GetFunc?SWELLAPI_GetFunc(api_tab[x].name):0; - if (!*api_tab[x].func) - { - printf("SWELL API not found: %s\n",api_tab[x].name); -#ifdef SWELL_LOAD_SWELL_DYLIB - exit(1); -#endif - *api_tab[x].func = (void*)&dummyFunc; - } + void (*set_app_main)(INT_PTR (*AppMain)(int msg, INT_PTR parm1, INT_PTR parm2)); + *(void **)&set_app_main = dlsym(tmp,"SWELL_set_app_main"); + if (set_app_main) set_app_main(SWELLAppMain); + + __loaded_getfunc = SWELLAPI_GetFunc; + if (doinit(SWELLAPI_GetFunc)) exit(1); } } ~SwellAPPInitializer() @@ -116,19 +118,27 @@ class SwellAPPInitializer SwellAPPInitializer m_swell_appAPIinit; -#ifdef SWELL_LOAD_SWELL_DYLIB extern "C" __attribute__ ((visibility ("default"))) void *SWELLAPI_GetFunc(const char *name) { if (__loaded_getfunc) return __loaded_getfunc(name); return NULL; } -#endif +#else extern "C" __attribute__ ((visibility ("default"))) int SWELL_dllMain(HINSTANCE hInst, DWORD callMode, LPVOID _GetFunc) { + if (callMode == DLL_PROCESS_ATTACH) + { + if (!_GetFunc) return 0; + doinit((void *(*)(const char *)) _GetFunc); + } + // this returning 1 allows DllMain to be called, if available return 1; } #endif + + +#endif diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index da72b729..5dc76c07 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -710,6 +710,14 @@ HINSTANCE LoadLibrary(const char *fn) { return LoadLibraryGlobals(fn,false); } + +#ifndef SWELL_TARGET_OSX +extern "C" { + void *SWELLAPI_GetFunc(const char *name); +}; +#endif + + HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) { if (!fn || !*fn) return NULL; @@ -764,9 +772,13 @@ HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) *(void **)&SWELL_dllMain = GetProcAddress(rec,"SWELL_dllMain"); if (SWELL_dllMain) { - void *SWELLAPI_GetFunc(const char *name); - - if (!SWELL_dllMain(rec,DLL_PROCESS_ATTACH,(void*)NULL)) // todo: eventually pass SWELLAPI_GetFunc, maybe? + if (!SWELL_dllMain(rec,DLL_PROCESS_ATTACH, +#ifdef SWELL_TARGET_OSX + NULL +#else + (void*)SWELLAPI_GetFunc +#endif + )) { FreeLibrary(rec); return 0; From e5f188894a12550afeba91c3054ebb1cbe8c423b Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 16:25:39 -0400 Subject: [PATCH 046/144] swell: fix incorrect API call in NSAccessibility wrapper -- from a6d314a9 --- WDL/wingui/virtwnd-nsaccessibility.mm | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/WDL/wingui/virtwnd-nsaccessibility.mm b/WDL/wingui/virtwnd-nsaccessibility.mm index 27a55a41..036d4b90 100644 --- a/WDL/wingui/virtwnd-nsaccessibility.mm +++ b/WDL/wingui/virtwnd-nsaccessibility.mm @@ -475,13 +475,12 @@ - (void)accessibilitySetValue:(id)value forAttribute:(NSString *)attribute // parameterized attribute methods - (NSArray *)accessibilityParameterizedAttributeNames { - { - const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; - if (!type) type=""; - //NSLog(@"accessibilityParameterizedAttributeNames: %@ %s %p\n",@"",type,m_br->vwnd); - } - return [NSArray arrayWithObjects:nil count:0]; - return nil; + // { +// const char *type = m_br->vwnd ? m_br->vwnd->GetType() : NULL; +// if (!type) type=""; +// NSLog(@"accessibilityParameterizedAttributeNames: %@ %s %p\n",@"",type,m_br->vwnd); +// } + return [NSArray array]; } - (id)accessibilityAttributeValue:(NSString *)attribute forParameter:(id)parameter { From 0c3b3bd54b55c90d75a17ab42dbce7175bf7bc23 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 17:07:37 -0400 Subject: [PATCH 047/144] wdlcstring: use INT_PTR for count parameter for lstrcpyn_safe/lstrcat/snprintf_append -- from 5ce60a71 --- WDL/wdlcstring.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/WDL/wdlcstring.h b/WDL/wdlcstring.h index 60c8ebcc..71a248e6 100644 --- a/WDL/wdlcstring.h +++ b/WDL/wdlcstring.h @@ -72,10 +72,10 @@ extern "C" { #ifdef _WDL_CSTRING_IF_ONLY_ - void lstrcpyn_safe(char *o, const char *in, int count); - void lstrcatn(char *o, const char *in, int count); - void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, int count, const char *format, ...); - void vsnprintf_append(char *o, int count, const char *format, va_list va); + void lstrcpyn_safe(char *o, const char *in, INT_PTR count); + void lstrcatn(char *o, const char *in, INT_PTR count); + void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...); + void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va); const char *WDL_get_filepart(const char *str); // returns whole string if no dir chars const char *WDL_get_fileext(const char *str); // returns ".ext" or end of string "" if no extension @@ -122,7 +122,7 @@ extern "C" { } #endif - _WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, int count) + _WDL_CSTRING_PREFIX void lstrcpyn_safe(char *o, const char *in, INT_PTR count) { if (count>0) { @@ -131,7 +131,7 @@ extern "C" { } } - _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, int count) + _WDL_CSTRING_PREFIX void lstrcatn(char *o, const char *in, INT_PTR count) { if (count>0) { @@ -218,7 +218,7 @@ extern "C" { return p-str; } - _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, int count, const char *format, ...) + _WDL_CSTRING_PREFIX void WDL_VARARG_WARN(printf,3,4) snprintf_append(char *o, INT_PTR count, const char *format, ...) { if (count>0) { @@ -230,7 +230,7 @@ extern "C" { } } - _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, int count, const char *format, va_list va) + _WDL_CSTRING_PREFIX void vsnprintf_append(char *o, INT_PTR count, const char *format, va_list va) { if (count>0) { From 9c5100a11b2dade5bac79fc5337eb23a740927ea Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 17:37:58 -0400 Subject: [PATCH 048/144] WDL_BitField: fix sign warning -- from 67601c65 --- WDL/bitfield.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/bitfield.h b/WDL/bitfield.h index 4f636907..bd085140 100644 --- a/WDL/bitfield.h +++ b/WDL/bitfield.h @@ -18,13 +18,13 @@ class WDL_BitField // ultra simple bit field { const unsigned char mask = 1<<(idx&7); idx>>=3; - return idx < m_hb.GetSize() && (((unsigned char *)m_hb.Get())[idx]&mask); + return idx < (unsigned int)m_hb.GetSize() && (((unsigned char *)m_hb.Get())[idx]&mask); } void Set(unsigned int idx) { const unsigned char mask = 1<<(idx&7); idx>>=3; - if (idx < m_hb.GetSize()) ((unsigned char *)m_hb.Get())[idx] |= mask; + if (idx < (unsigned int)m_hb.GetSize()) ((unsigned char *)m_hb.Get())[idx] |= mask; } private: From 5cc932b86e4547c3491d302f529dfec0de2f6cdc Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 2 Apr 2018 21:50:05 -0400 Subject: [PATCH 049/144] swell-lice: improve focus indicators for controls, tweak checkbox layouts -- from 0aa6eba3 and 7eb1cebd --- WDL/swell/swell-internal.h | 2 +- WDL/swell/swell-wnd-generic.cpp | 61 +++++++++++++++++---------------- 2 files changed, 33 insertions(+), 30 deletions(-) diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h index 8a770c4c..49108c8f 100644 --- a/WDL/swell/swell-internal.h +++ b/WDL/swell/swell-internal.h @@ -1076,7 +1076,7 @@ static void __listview_mergesort_internal(void *base, size_t nmemb, size_t size, f(group_text,RGB(0,0,0)) \ fd(group_shadow, RGB(96,96,96), _3dshadow) \ fd(group_hilight, RGB(224,224,224), _3dhilight) \ - f(focus_hilight, RGB(192,192,255)) \ + f(focus_hilight, RGB(140,190,233)) \ diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 5d2bec2f..0761718a 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -1232,7 +1232,7 @@ static bool draw_focus_indicator(HWND hwnd, HDC hdc, const RECT *drawr) if (drawr) r=*drawr; else GetClientRect(hwnd,&r); - HBRUSH br = CreateSolidBrushAlpha(g_swell_ctheme.focus_hilight,0.75f); + HBRUSH br = CreateSolidBrushAlpha(g_swell_ctheme.focus_hilight,.75f); tr=r; tr.right = tr.left+sz; FillRect(hdc,&tr,br); tr=r; tr.left = tr.right-sz; FillRect(hdc,&tr,br); tr=r; tr.left+=sz; tr.right-=sz; @@ -1373,10 +1373,37 @@ static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA EndPaint(hwnd,&ps); return 0; } - if (sf == BS_AUTO3STATE || sf == BS_AUTOCHECKBOX || sf == BS_AUTORADIOBUTTON) + + const bool ischk = sf == BS_AUTO3STATE || sf == BS_AUTOCHECKBOX || sf == BS_AUTORADIOBUTTON; + if (!ischk) + { + Draw3DBox(ps.hdc,&r,g_swell_ctheme.button_bg, + g_swell_ctheme.button_hilight, + g_swell_ctheme.button_shadow,pressed); + + if (hwnd->m_style & BS_LEFT) + r.left+=2; + else + f|=DT_CENTER; + if (pressed) + { + const int pad = SWELL_UI_SCALE(2); + r.left+=pad; + r.top+=pad; + if (s->bitmap) { r.right+=pad; r.bottom+=pad; } + } + } + + if (draw_focus_indicator(hwnd,ps.hdc,NULL)) + { + KillTimer(hwnd,1); + SetTimer(hwnd,1,100,NULL); + } + + if (ischk) { - const int chksz = SWELL_UI_SCALE(12); - RECT tr={r.left,(r.top+r.bottom)/2-chksz/2,r.left+chksz}; + const int chksz = SWELL_UI_SCALE(12), chki = SWELL_UI_SCALE(2); + RECT tr={r.left+chki,(r.top+r.bottom)/2-chksz/2,r.left+chki+chksz}; tr.bottom = tr.top+chksz; HPEN pen=CreatePen(PS_SOLID,0,g_swell_ctheme.checkbox_fg); @@ -1432,29 +1459,11 @@ static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA } SelectObject(ps.hdc,oldPen); DeleteObject(pen); - r.left += chksz + SWELL_UI_SCALE(4); + r.left += chksz + SWELL_UI_SCALE(5); SetTextColor(ps.hdc, hwnd->m_enabled ? g_swell_ctheme.checkbox_text : g_swell_ctheme.checkbox_text_disabled); } - else - { - Draw3DBox(ps.hdc,&r,g_swell_ctheme.button_bg, - g_swell_ctheme.button_hilight, - g_swell_ctheme.button_shadow,pressed); - - if (hwnd->m_style & BS_LEFT) - r.left+=2; - else - f|=DT_CENTER; - if (pressed) - { - const int pad = SWELL_UI_SCALE(2); - r.left+=pad; - r.top+=pad; - if (s->bitmap) { r.right+=pad; r.bottom+=pad; } - } - } if (s->bitmap) { @@ -1475,12 +1484,6 @@ static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA if (buf[0]) DrawText(ps.hdc,buf,-1,&r,f); } - if (draw_focus_indicator(hwnd,ps.hdc,NULL)) - { - KillTimer(hwnd,1); - SetTimer(hwnd,1,100,NULL); - } - EndPaint(hwnd,&ps); } } From c50082706fb13b0e1bccb33c6e647db133d4fc2c Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 3 Apr 2018 09:43:07 -0400 Subject: [PATCH 050/144] WDL_FileRead: cast m_fsize to size_t for mmap/pread/etc -- from 21190fe6 --- WDL/fileread.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/WDL/fileread.h b/WDL/fileread.h index 8e6fbc42..dd2c9a6d 100644 --- a/WDL/fileread.h +++ b/WDL/fileread.h @@ -278,14 +278,14 @@ class WDL_FileRead__ReadEnt { if (m_fsize >= mmap_minsize) { - m_mmap_view = mmap(NULL,m_fsize,PROT_READ,MAP_SHARED,m_filedes,0); + m_mmap_view = mmap(NULL,(size_t)m_fsize,PROT_READ,MAP_SHARED,m_filedes,0); if (m_mmap_view == MAP_FAILED) m_mmap_view = 0; else m_fsize_maychange=false; } else { - m_mmap_totalbufmode = malloc(m_fsize); - m_fsize = pread(m_filedes,m_mmap_totalbufmode,m_fsize,0); + m_mmap_totalbufmode = malloc((size_t)m_fsize); + m_fsize = pread(m_filedes,m_mmap_totalbufmode,(size_t)m_fsize,0); m_fsize_maychange=false; } } @@ -334,7 +334,7 @@ class WDL_FileRead__ReadEnt if (m_fh != INVALID_HANDLE_VALUE) CloseHandle(m_fh); m_fh=INVALID_HANDLE_VALUE; #elif defined(WDL_POSIX_NATIVE_READ) - if (m_mmap_view) munmap(m_mmap_view,m_fsize); + if (m_mmap_view) munmap(m_mmap_view,(size_t)m_fsize); m_mmap_view=0; if (m_filedes>=0) { From c25b6bcea6f9c4df065e3bbb4cf3a2232696c413 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 3 Apr 2018 18:51:58 -0400 Subject: [PATCH 051/144] swell-linux: never allow RT priorities above 40 for THREAD_PRIORITY_ABOVE_NORMAL -- from 022a951a --- WDL/swell/swell.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 5dc76c07..b80b46f1 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -491,6 +491,8 @@ BOOL SetThreadPriority(HANDLE hand, int prio) { lb--; if (prio < THREAD_PRIORITY_ABOVE_NORMAL) lb--; + + if (lb > 40) lb = 40; // if not HIGHEST or higher, do not permit RT priority of more than 40 } } param.sched_priority = lb < 1 ? 1 : lb; From 43c25e20bde6f3e32c85c12d4bfb18688f43cc15 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 5 Apr 2018 15:05:52 -0400 Subject: [PATCH 052/144] swell-generic: fix some dylib terminology -- from 73181cdb --- WDL/swell/swell-appstub-generic.cpp | 4 ++-- WDL/swell/swell-modstub-generic.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/WDL/swell/swell-appstub-generic.cpp b/WDL/swell/swell-appstub-generic.cpp index 78d20f18..f1286c23 100644 --- a/WDL/swell/swell-appstub-generic.cpp +++ b/WDL/swell/swell-appstub-generic.cpp @@ -24,7 +24,7 @@ #ifndef SWELL_PROVIDED_BY_APP // only add this file to your project if you are an application that wishes to publish the SWELL API to its modules/plugins -// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub.mm +// the modules should be compiled using SWELL_PROVIDED_BY_APP and include swell-modstub-generic.cpp #undef _WDL_SWELL_H_API_DEFINED_ #undef SWELL_API_DEFINE @@ -73,7 +73,7 @@ INT_PTR SWELLAppMain(int msg, INT_PTR parm1, INT_PTR parm2) { chk=1; *(void **)&s_AppMain = dlsym(NULL,"SWELLAppMain"); - printf("swell-dylib: used legacy SWELLAppMain get to get %p\n",s_AppMain); + printf("libSwell: used legacy SWELLAppMain get to get %p\n",s_AppMain); } // end temp code diff --git a/WDL/swell/swell-modstub-generic.cpp b/WDL/swell/swell-modstub-generic.cpp index e063c526..3aa9e3f5 100644 --- a/WDL/swell/swell-modstub-generic.cpp +++ b/WDL/swell/swell-modstub-generic.cpp @@ -26,7 +26,7 @@ extern "C" { #include "swell.h" }; -// only include this file in projects that are linked to swell.dylib +// only include this file in projects that are linked to libSwell.so struct SWELL_CursorResourceIndex *SWELL_curmodule_cursorresource_head; struct SWELL_DialogResourceIndex *SWELL_curmodule_dialogresource_head; From aa662c57a42acb3e74fe88640d2e5e5ca9ab7a8b Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 5 Apr 2018 22:55:42 -0400 Subject: [PATCH 053/144] swell-misc.mm: allow defining SWELL_NO_POSTMESSAGE -- from 63b523fb --- WDL/swell/swell-misc.mm | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-misc.mm b/WDL/swell/swell-misc.mm index 8e3b14db..4803ebb7 100644 --- a/WDL/swell/swell-misc.mm +++ b/WDL/swell/swell-misc.mm @@ -336,8 +336,10 @@ void SWELL_RunEvents() } TimerInfoRec; static TimerInfoRec *m_timer_list; static WDL_Mutex m_timermutex; +#ifndef SWELL_NO_POSTMESSAGE static pthread_t m_pmq_mainthread; static void SWELL_pmq_settimer(HWND h, UINT_PTR timerid, UINT rate, TIMERPROC tProc); +#endif UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc) { @@ -345,11 +347,13 @@ UINT_PTR SetTimer(HWND hwnd, UINT_PTR timerid, UINT rate, TIMERPROC tProc) if (hwnd && !timerid) return 0; +#ifndef SWELL_NO_POSTMESSAGE if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread) { SWELL_pmq_settimer(hwnd,timerid,(rate==(UINT)-1)?((UINT)-2):rate,tProc); return timerid; } +#endif if (hwnd && ![(id)hwnd respondsToSelector:@selector(SWELL_Timer:)]) @@ -433,11 +437,13 @@ BOOL KillTimer(HWND hwnd, UINT_PTR timerid) if (!hwnd && !timerid) return FALSE; WDL_MutexLock lock(&m_timermutex); +#ifndef SWELL_NO_POSTMESSAGE if (timerid != ~(UINT_PTR)0 && m_pmq_mainthread && pthread_self()!=m_pmq_mainthread) { SWELL_pmq_settimer(hwnd,timerid,~(UINT)0,NULL); return TRUE; } +#endif BOOL rv=FALSE; // don't allow removing all global timers @@ -474,6 +480,7 @@ BOOL KillTimer(HWND hwnd, UINT_PTR timerid) } +#ifndef SWELL_NO_POSTMESSAGE ///////// PostMessage emulation @@ -681,7 +688,7 @@ BOOL SWELL_Internal_PostMessage(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPara return ret; } - +#endif static bool s_rightclickemulate=true; From 58532e0a585d284811d71d60ce6acd626b8f2e20 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 9 Apr 2018 19:46:09 -0400 Subject: [PATCH 054/144] LICE: use double parameters for bezier drawing functions -- from b1c0a5bd --- WDL/lice/lice.h | 16 +++++----- WDL/lice/lice_line.cpp | 72 +++++++++++++++++++++--------------------- 2 files changed, 44 insertions(+), 44 deletions(-) diff --git a/WDL/lice/lice.h b/WDL/lice/lice.h index 383b1082..51f33271 100644 --- a/WDL/lice/lice.h +++ b/WDL/lice/lice.h @@ -482,20 +482,20 @@ void LICE_DrawMonoGlyph(LICE_IBitmap* dest, int x, int y, LICE_pixel color, cons // quadratic bezier // tol means try to draw segments no longer than tol px -void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl, float yctl, float xend, float yend, - LICE_pixel color, float alpha=1.0f, int mode=0, bool aa=true, float tol=0.0); +void LICE_DrawQBezier(LICE_IBitmap* dest, double xstart, double ystart, double xctl, double yctl, double xend, double yend, + LICE_pixel color, float alpha=1.0f, int mode=0, bool aa=true, double tol=0.0); // cubic bezier // tol means try to draw segments no longer than tol px -void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, LICE_pixel color, float alpha=1.0f, int mode=0, bool aa=true, float tol=0.0f); +void LICE_DrawCBezier(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, LICE_pixel color, float alpha=1.0f, int mode=0, bool aa=true, double tol=0.0); // vertical fill from y=yfill -void LICE_FillCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, int yfill, LICE_pixel color, float alpha=1.0f, int mode=0, float tol=0.0f); +void LICE_FillCBezier(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, int yfill, LICE_pixel color, float alpha=1.0f, int mode=0, double tol=0.0); // horizontal fill from x=xfill -void LICE_FillCBezierX(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, int xfill, LICE_pixel color, float alpha=1.0f, int mode=0, float tol=0.0f); +void LICE_FillCBezierX(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, int xfill, LICE_pixel color, float alpha=1.0f, int mode=0, double tol=0.0); // convenience functions void LICE_DrawRect(LICE_IBitmap *dest, int x, int y, int w, int h, LICE_pixel color, float alpha=1.0f, int mode=0); diff --git a/WDL/lice/lice_line.cpp b/WDL/lice/lice_line.cpp index 3f1719b0..62fd0357 100644 --- a/WDL/lice/lice_line.cpp +++ b/WDL/lice/lice_line.cpp @@ -948,8 +948,8 @@ static void DoBezierFillSegmentX(LICE_IBitmap* dest, int x1, int y1, int x2, int // quadratic bezier ... NOT TESTED YET // attempt to draw segments no longer than tol px -void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl, float yctl, float xend, float yend, - LICE_pixel color, float alpha, int mode, bool aa, float tol) +void LICE_DrawQBezier(LICE_IBitmap* dest, double xstart, double ystart, double xctl, double yctl, double xend, double yend, + LICE_pixel color, float alpha, int mode, bool aa, double tol) { if (!dest) return; @@ -964,10 +964,10 @@ void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl double len = sqrt((xctl-xstart)*(xctl-xstart)+(yctl-ystart)*(yctl-ystart)); len += sqrt((xend-xctl)*(xend-xctl)+(yend-yctl)*(yend-yctl)); - float xlo = xstart; - float xhi = xend; - float ylo = ystart; - float yhi = yend; + double xlo = xstart; + double xhi = xend; + double ylo = ystart; + double yhi = yend; double tlo = 0.0; double thi = 1.0; @@ -991,9 +991,9 @@ void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl double dt = (thi-tlo)/(double)nsteps; double t = tlo+dt; - float lastx = xlo; - float lasty = ylo; - float x, y; + double lastx = xlo; + double lasty = ylo; + double x, y; int i; for (i = 1; i < nsteps; ++i) { @@ -1007,10 +1007,10 @@ void LICE_DrawQBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl } -static int CBezPrep(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, float tol, bool xbasis, +static int CBezPrep(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, double tol, bool xbasis, double* ax, double* bx, double* cx, double* dx, double* ay, double* by, double* cy, double* dy, - float* xlo, float* xhi, float* ylo, float* yhi, double* tlo, double* thi) + double* xlo, double* xhi, double* ylo, double* yhi, double* tlo, double* thi) { if (!dest) return 0; @@ -1042,12 +1042,12 @@ static int CBezPrep(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, if (*xlo < 0.0f) { *xlo = 0.0f; - *ylo = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xlo, (float*)0, (float*)0, (double*)0, tlo); + *ylo = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xlo, (double*)NULL, (double*)NULL, (double*)NULL, tlo); } - if (*xhi > (float)w) + if (*xhi > w) { - *xhi = (float)(w); - *yhi = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xhi, (float*)0, (float*)0, thi, (double*)0); + *xhi = w; + *yhi = LICE_CBezier_GetY(xstart, xctl1, xctl2, xend, ystart, yctl1, yctl2, yend, *xhi, (double*)NULL, (double*)(double*)NULL, thi, (double*)NULL); } if ((xbasis && *xlo > *xhi) || (!xbasis && *ylo > *yhi)) { @@ -1061,8 +1061,8 @@ static int CBezPrep(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, return nsteps; } -void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, LICE_pixel color, float alpha, int mode, bool aa, float tol) +void LICE_DrawCBezier(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, LICE_pixel color, float alpha, int mode, bool aa, double tol) { if (!dest) return; @@ -1075,7 +1075,7 @@ void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl #endif double ax, bx, cx, dx, ay, by, cy, dy; - float xlo, xhi, ylo, yhi; + double xlo, xhi, ylo, yhi; double tlo, thi; int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, true, &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); @@ -1084,9 +1084,9 @@ void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl double dt = (thi-tlo)/(double)nsteps; double t = tlo+dt; - float lastx = xlo; - float lasty = ylo; - float x, y; + double lastx = xlo; + double lasty = ylo; + double x, y; int i; for (i = 1; i < nsteps-1; ++i) { @@ -1099,13 +1099,13 @@ void LICE_DrawCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl LICE_FLine(dest, lastx, lasty, xhi, yhi, color, alpha, mode, aa); } -void LICE_FillCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, int yfill, LICE_pixel color, float alpha, int mode, float tol) +void LICE_FillCBezier(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, int yfill, LICE_pixel color, float alpha, int mode, double tol) { if (!dest) return; double ax, bx, cx, dx, ay, by, cy, dy; - float xlo, xhi, ylo, yhi; + double xlo, xhi, ylo, yhi; double tlo, thi; int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, true, &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); @@ -1116,7 +1116,7 @@ void LICE_FillCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl int lastfillx = (int)xlo; int lastfilly = (int)(ylo+0.5f); - float x, y; + double x, y; int i; for (i = 1; i < nsteps-1; ++i) { @@ -1137,13 +1137,13 @@ void LICE_FillCBezier(LICE_IBitmap* dest, float xstart, float ystart, float xctl } } -void LICE_FillCBezierX(LICE_IBitmap* dest, float xstart, float ystart, float xctl1, float yctl1, - float xctl2, float yctl2, float xend, float yend, int xfill, LICE_pixel color, float alpha, int mode, float tol) +void LICE_FillCBezierX(LICE_IBitmap* dest, double xstart, double ystart, double xctl1, double yctl1, + double xctl2, double yctl2, double xend, double yend, int xfill, LICE_pixel color, float alpha, int mode, double tol) { if (!dest) return; double ax, bx, cx, dx, ay, by, cy, dy; - float xlo, xhi, ylo, yhi; + double xlo, xhi, ylo, yhi; double tlo, thi; int nsteps = CBezPrep(dest, xstart, ystart, xctl1, yctl1, xctl2, yctl2, xend, yend, tol, false, &ax, &bx, &cx, &dx, &ay, &by, &cy, &dy, &xlo, &xhi, &ylo, &yhi, &tlo, &thi); @@ -1154,7 +1154,7 @@ void LICE_FillCBezierX(LICE_IBitmap* dest, float xstart, float ystart, float xct int lastfillx = (int)(xlo+0.5f); int lastfilly = (int)ylo; - float x, y; + double x, y; int i; for (i = 1; i < nsteps-1; ++i) { @@ -1329,8 +1329,8 @@ static int FindXOnSegment(int x1, int y1, int x2, int y2, int ty) } if (ty <= y1) return x1; if (ty >= y2) return x2; - float dxdy = (float)(x2-x1)/(float)(y2-y1); - return x1+(int)((float)(ty-y1)*dxdy); + const double dxdy = (x2-x1)/(double)(y2-y1); + return x1+(int)((ty-y1)*dxdy); } static int FindYOnSegment(int x1, int y1, int x2, int y2, int tx) @@ -1342,8 +1342,8 @@ static int FindYOnSegment(int x1, int y1, int x2, int y2, int tx) } if (tx <= x1) return y1; if (tx >= x2) return y2; - float dydx = (float)(y2-y1)/(float)(x2-x1); - return y1+(int)((float)(tx-x1)*dydx); + const double dydx = (y2-y1)/(double)(x2-x1); + return y1+(int)((tx-x1)*dydx); } void LICE_FillTrapezoid(LICE_IBitmap* dest, int x1a, int x1b, int y1, int x2a, int x2b, int y2, LICE_pixel color, float alpha, int mode) @@ -1496,13 +1496,13 @@ static int _ysort(const void* a, const void* b) static int FindNextEdgeVertex(int* xy, int a, int n, int dir) { bool init = false; - float dxdy_best = 0.0f; + double dxdy_best = 0.0f; int i, ilo = a; for (i = a+1; i < n; ++i) { if (_Y(i) == _Y(a)) continue; - float dxdy = (float)(_X(i)-_X(a))/(float)(_Y(i)-_Y(a)); + const double dxdy = (_X(i)-_X(a))/(double)(_Y(i)-_Y(a)); if (!init || dxdy == dxdy_best || (dir < 0 && dxdy < dxdy_best) || (dir > 0 && dxdy > dxdy_best)) { init = true; From efaf3ad3ae2b9774c907d44f89fbfbae7b92127e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 10 Apr 2018 21:24:45 -0400 Subject: [PATCH 055/144] virtwnd: fix potential Windows accessibility related crash [t=205483] -- from 23743904 --- WDL/wingui/virtwnd-iaccessible.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/wingui/virtwnd-iaccessible.cpp b/WDL/wingui/virtwnd-iaccessible.cpp index 3481bb26..70fd05cb 100644 --- a/WDL/wingui/virtwnd-iaccessible.cpp +++ b/WDL/wingui/virtwnd-iaccessible.cpp @@ -216,7 +216,7 @@ class CVWndAccessible : public IAccessible *ppdispParent = NULL; - if (__CreateStdAccessibleObject) + if (__CreateStdAccessibleObject && m_br.vwnd) { HWND realparent = m_br.vwnd->GetRealParent(); if (realparent) From 029f5a0e1252ecd196251e52fd5829e17790e61d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 29 Apr 2018 20:59:03 -0400 Subject: [PATCH 056/144] add win32_printf.h to implement printf() for debugging -- from 3fdc5685 --- WDL/win32_printf.h | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 WDL/win32_printf.h diff --git a/WDL/win32_printf.h b/WDL/win32_printf.h new file mode 100644 index 00000000..701e4d83 --- /dev/null +++ b/WDL/win32_printf.h @@ -0,0 +1,27 @@ +#ifndef _WDL_WIN32_PRINTF_H_ +#define _WDL_WIN32_PRINTF_H_ + +#include +#ifdef printf +#undef printf +#endif +#define printf wdl_printf + +// this file is designed to be temporarily included when printf() debugging on win32 + + +static void wdl_printf(const char *format, ...) +{ + char tmp[3800]; + int rv; + va_list va; + va_start(va,format); + tmp[0]=0; + rv=_vsnprintf(tmp,sizeof(tmp),format,va); // returns -1 if over, and does not null terminate, ugh + va_end(va); + + if (rv < 0 || rv>=(int)sizeof(tmp)-1) tmp[sizeof(tmp)-1]=0; + OutputDebugStringA(tmp); +} + +#endif From cffc3f6f145db48ceb993779fb64da47b248b1bc Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 6 May 2018 19:42:45 -0400 Subject: [PATCH 057/144] swell: support https:// via ShellExecute() -- from 2ef8006d --- WDL/swell/swell-wnd-generic.cpp | 2 +- WDL/swell/swell-wnd.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 0761718a..c91792cd 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -7515,7 +7515,7 @@ BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const if (!content1 || !*content1) return FALSE; - if (!strnicmp(content1,"http://",7)) + if (!strnicmp(content1,"http://",7) || !strnicmp(content1,"https://",8)) { argv[0] = xdg; argv[1] = content1; diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm index e5c0227a..a90c3a48 100644 --- a/WDL/swell/swell-wnd.mm +++ b/WDL/swell/swell-wnd.mm @@ -5847,7 +5847,7 @@ void ListView_SetTextColor(HWND hwnd, int color) BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah) { - if (content1 && !strnicmp(content1,"http://",7)) + if (content1 && (!strnicmp(content1,"http://",7) || !strnicmp(content1,"https://",8))) { NSWorkspace *wk = [NSWorkspace sharedWorkspace]; if (!wk) return FALSE; From ed2812b54ea8990c23cf7dd6db3afa69487077f3 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 7 May 2018 16:25:19 -0400 Subject: [PATCH 058/144] swell-generic: use %.1000s for some formats -- from b6a68c5c --- WDL/swell/swell-miscdlg-generic.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp index dd1c20bc..f978d322 100644 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -690,7 +690,7 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L DIR *dir = opendir(buf); if (!dir) { - snprintf(msg,sizeof(msg),"Error opening directory:\r\n\r\n%s\r\n\r\nCreate?",buf); + snprintf(msg,sizeof(msg),"Error opening directory:\r\n\r\n%.1000s\r\n\r\nCreate?",buf); if (MessageBox(hwnd,msg,"Create directory?",MB_OKCANCEL)==IDCANCEL) return 0; CreateDirectory(buf,NULL); dir=opendir(buf); @@ -727,7 +727,7 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L if (buf[strlen(buf)-1] == '/') goto treatAsDir; if (!stat64(buf,&st)) { - snprintf(msg,sizeof(msg),"File exists:\r\n\r\n%s\r\n\r\nOverwrite?",buf); + snprintf(msg,sizeof(msg),"File exists:\r\n\r\n%.1000s\r\n\r\nOverwrite?",buf); if (MessageBox(hwnd,msg,"Overwrite file?",MB_OKCANCEL)==IDCANCEL) return 0; } } From ebe8ac1752c0d19f03a319b08154a55ee1fdeb7e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 20 May 2018 22:28:15 -0400 Subject: [PATCH 059/144] swell-generic: print error when dlopen() fails -- from a5de2ab0 --- WDL/swell/swell.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index b80b46f1..f77caf53 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -753,7 +753,14 @@ HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) #endif { inst=dlopen(fn,RTLD_NOW|(symbolsAsGlobals?RTLD_GLOBAL:RTLD_LOCAL)); - if (!inst) return 0; + if (!inst) + { +#ifndef SWELL_TARGET_OSX + const char *err = dlerror(); + printf("swell: error calling dlopen(%s): %s\n",fn,err ? err : "(unknown)"); +#endif + return 0; + } } WDL_MutexLock lock(&s_libraryMutex); From dc91ab0c20920afc11d462cea03e3298e4b1a4e3 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 23 May 2018 18:52:59 -0400 Subject: [PATCH 060/144] add WDL_HeapBuf/WDL_TypedBuf::GetFast() -- from 2b6005d0 --- WDL/heapbuf.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WDL/heapbuf.h b/WDL/heapbuf.h index 226845be..0371df82 100644 --- a/WDL/heapbuf.h +++ b/WDL/heapbuf.h @@ -52,7 +52,8 @@ class WDL_HeapBuf void *Resize(int newsize, bool resizedown=true); void CopyFrom(const WDL_HeapBuf *hb, bool exactCopyOfConfig=false); #endif - void *Get() const { return m_size?m_buf:NULL; } + void *Get() const { return m_size?m_buf:NULL; } // returns NULL if size is 0 + void *GetFast() const { return m_buf; } // returns last buffer if size is 0 int GetSize() const { return m_size; } void *GetAligned(int align) const { return (void *)(((UINT_PTR)Get() + (align-1)) & ~(UINT_PTR)(align-1)); } @@ -258,6 +259,7 @@ template class WDL_TypedBuf { public: PTRTYPE *Get() const { return (PTRTYPE *) m_hb.Get(); } + PTRTYPE *GetFast() const { return (PTRTYPE *) m_hb.GetFast(); } int GetSize() const { return m_hb.GetSize()/(unsigned int)sizeof(PTRTYPE); } PTRTYPE *Resize(int newsize, bool resizedown = true) { return (PTRTYPE *)m_hb.Resize(newsize*sizeof(PTRTYPE),resizedown); } From 43246c30afe8b464b6de74fe2dfb44f9b847a928 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 23 May 2018 18:54:05 -0400 Subject: [PATCH 061/144] swell-generic: improve dlopen error messages -- from 14bdbd8c --- WDL/swell/swell.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index f77caf53..dcc3a466 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -757,7 +757,7 @@ HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) { #ifndef SWELL_TARGET_OSX const char *err = dlerror(); - printf("swell: error calling dlopen(%s): %s\n",fn,err ? err : "(unknown)"); + printf("swell: dlopen() failed: %s\n",err ? err : fn); #endif return 0; } From 79d87918b9b0a5f5a0d0ec587196244b106eea0b Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 25 May 2018 07:54:28 -0400 Subject: [PATCH 062/144] swell-generic: do not show dlopen() errors when not loading a full path -- from 702da59d --- WDL/swell/swell.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index dcc3a466..90d1c774 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -756,8 +756,11 @@ HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) if (!inst) { #ifndef SWELL_TARGET_OSX - const char *err = dlerror(); - printf("swell: dlopen() failed: %s\n",err ? err : fn); + if (fn[0] == '/') + { + const char *err = dlerror(); + printf("swell: dlopen() failed: %s\n",err ? err : fn); + } #endif return 0; } From ab5d7c7af64e49bccf32ecccbd4aec6fa0ae21aa Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 25 May 2018 08:24:33 -0400 Subject: [PATCH 063/144] swell-generic: SW_SHOW behaves as SW_SHOWNA if window is already visible -- from cbcdfce1 --- WDL/swell/swell-wnd-generic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index c91792cd..54cc8558 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -935,6 +935,7 @@ void ShowWindow(HWND hwnd, int cmd) if (cmd==SW_SHOW||cmd==SW_SHOWNA) { + if (hwnd->m_visible) cmd = SW_SHOWNA; // do not take focus if already visible hwnd->m_visible=true; } else if (cmd==SW_HIDE) From 6009a4a8052d053773cba0ffb2bf124f095a5b23 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 25 May 2018 08:42:48 -0400 Subject: [PATCH 064/144] swell-generic: only print dlopen failures if file exists -- from ba53df1c --- WDL/swell/swell.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 90d1c774..07ed05d4 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -756,7 +756,8 @@ HINSTANCE LoadLibraryGlobals(const char *fn, bool symbolsAsGlobals) if (!inst) { #ifndef SWELL_TARGET_OSX - if (fn[0] == '/') + struct stat ss; + if (fn[0] == '/' && !stat(fn,&ss) && !(ss.st_mode&S_IFDIR)) { const char *err = dlerror(); printf("swell: dlopen() failed: %s\n",err ? err : fn); From 9bf46a424842d1a4a0f8cab5c7543e7d7b74b298 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 26 May 2018 09:56:40 -0400 Subject: [PATCH 065/144] swell: use pkg-config freetype2 rather than freetype-config -- from bb89e8f7 --- WDL/swell/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index 3d510cf4..70edaaeb 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -101,9 +101,9 @@ ifndef NOGDK OBJS += $(LICE_OBJS) ifndef NOFREETYPE - CFLAGS += -DSWELL_FREETYPE $(shell freetype-config --cflags) + CFLAGS += -DSWELL_FREETYPE $(shell $(PKG_CONFIG) --cflags freetype2) ifndef PRELOAD_GDK - LINKEXTRA += $(shell freetype-config --libs) + LINKEXTRA += $(shell $(PKG_CONFIG) --libs freetype2) endif endif endif From aa8d4180c93a6c3c3e2004c722969a9b33ec0d2e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 21 May 2018 17:10:22 -0400 Subject: [PATCH 066/144] SWELL-cocoa: better support dynamic WS_EX_ACCEPTFILES setting -- from 85df721d --- WDL/swell/swell-dlg.mm | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-dlg.mm b/WDL/swell/swell-dlg.mm index 5e87044e..f7abc4ff 100644 --- a/WDL/swell/swell-dlg.mm +++ b/WDL/swell/swell-dlg.mm @@ -1470,8 +1470,22 @@ - (BOOL)acceptsFirstResponder -(void)swellSetExtendedStyle:(LONG)st { - if (st&WS_EX_ACCEPTFILES) m_supports_ddrop=true; - else m_supports_ddrop=false; + if (st&WS_EX_ACCEPTFILES) + { + if (!m_supports_ddrop) + { + [self registerForDraggedTypes:[NSArray arrayWithObjects:NSFilenamesPboardType, NSFilesPromisePboardType, nil]]; + m_supports_ddrop=true; + } + } + else + { + if (m_supports_ddrop) + { + [self unregisterDraggedTypes]; + m_supports_ddrop=false; + } + } } -(LONG)swellGetExtendedStyle { From 9a1e4d1e4cf7682c06548e686efacf3870f34f5a Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 21 May 2018 16:54:35 -0400 Subject: [PATCH 067/144] eel_lice: add gfx_getdropfile -- from 2af2ffef --- WDL/eel2/eel_lice.h | 55 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index 922c0699..08131451 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -284,6 +284,7 @@ class eel_lice_state EEL_F gfx_loadimg(void *opaque, int img, EEL_F loadFrom); EEL_F gfx_setfont(void *opaque, int np, EEL_F **parms); EEL_F gfx_getfont(void *opaque, int np, EEL_F **parms); + EEL_F gfx_getdropfile(void *opaque, int np, EEL_F **parms); LICE_pixel getCurColor(); int getCurMode(); @@ -313,6 +314,8 @@ class eel_lice_state #endif int m_has_cap; // high 16 bits are current capture state, low 16 bits are temporary flags from mousedown bool m_has_had_getch; // set on first gfx_getchar(), makes mouse_cap updated with modifiers even when no mouse click is down + + WDL_PtrList m_ddrop_files; }; @@ -393,6 +396,7 @@ eel_lice_state::~eel_lice_state() if (m_gfx_fonts.Get()[x].font) LICE__DestroyFont(m_gfx_fonts.Get()[x].font); } } + m_ddrop_files.Empty(true,free); } int eel_lice_state::getCurMode() @@ -743,6 +747,12 @@ static EEL_F NSEEL_CGEN_CALL _gfx_loadimg(void *opaque, EEL_F *img, EEL_F *fr) return 0.0; } +static EEL_F NSEEL_CGEN_CALL _gfx_getdropfile(void *opaque, INT_PTR np, EEL_F **parms) +{ + eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); + if (ctx) return ctx->gfx_getdropfile(opaque,(int) np, parms); + return 0.0; +} static EEL_F NSEEL_CGEN_CALL _gfx_setimgdim(void *opaque, EEL_F *img, EEL_F *w, EEL_F *h) { eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); @@ -960,6 +970,25 @@ void eel_lice_state::gfx_getimgdim(EEL_F img, EEL_F *w, EEL_F *h) } } +EEL_F eel_lice_state::gfx_getdropfile(void *opaque, int np, EEL_F **parms) +{ + const int idx = (int) parms[0][0]; + if (idx<0) m_ddrop_files.Empty(true,free); + if (idx < 0 || idx >= m_ddrop_files.GetSize()) return 0.0; + +#ifdef NOT_EEL_STRING_UPDATE_STRING + NOT_EEL_STRING_UPDATE_STRING(parms[1][0],m_ddrop_files.Get(idx)); +#else + if (np > 1) + { + EEL_STRING_MUTEXLOCK_SCOPE + WDL_FastString *fs=NULL; + EEL_STRING_GET_FOR_WRITE(parms[1][0], &fs); + if (fs) fs->Set(m_ddrop_files.Get(idx)); + } +#endif + return 1.0; +} EEL_F eel_lice_state::gfx_loadimg(void *opaque, int img, EEL_F loadFrom) { @@ -1832,6 +1861,7 @@ void eel_lice_register() NSEEL_addfunc_varparm("gfx_setfont",1,NSEEL_PProc_THIS,&_gfx_setfont); NSEEL_addfunc_varparm("gfx_getfont",1,NSEEL_PProc_THIS,&_gfx_getfont); NSEEL_addfunc_varparm("gfx_set",1,NSEEL_PProc_THIS,&_gfx_set); + NSEEL_addfunc_varparm("gfx_getdropfile",1,NSEEL_PProc_THIS,&_gfx_getdropfile); } #endif @@ -1850,6 +1880,7 @@ static EEL_F * NSEEL_CGEN_CALL _gfx_update(void *opaque, EEL_F *n) eel_lice_state *ctx=EEL_LICE_GET_CONTEXT(opaque); if (ctx) { + ctx->m_ddrop_files.Empty(true,free); if (ctx->hwnd_standalone) { if (ctx->m_framebuffer_dirty) @@ -2055,7 +2086,7 @@ HWND eel_lice_state::create_wnd(HWND par, int isChild) { if (hwnd_standalone) return hwnd_standalone; #ifdef _WIN32 - return CreateWindowEx(0,eel_lice_standalone_classname,"", + return CreateWindowEx(WS_EX_ACCEPTFILES,eel_lice_standalone_classname,"", isChild ? (WS_CHILD|WS_TABSTOP) : (WS_POPUP|WS_CAPTION|WS_THICKFRAME|WS_SYSMENU),CW_USEDEFAULT,CW_USEDEFAULT,100,100,par,NULL,eel_lice_hinstance,this); #else return SWELL_CreateDialog(NULL,isChild ? NULL : ((const char *)(INT_PTR)0x400001),par,(DLGPROC)eel_lice_wndproc,(LPARAM)this); @@ -2271,6 +2302,7 @@ LRESULT WINAPI eel_lice_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar #else eel_lice_state *ctx=(eel_lice_state*)lParam; SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); + SetWindowLong(hwnd,GWL_EXSTYLE, GetWindowLong(hwnd,GWL_EXSTYLE) | WS_EX_ACCEPTFILES); #endif ctx->m_kb_queue_valid=0; ctx->hwnd_standalone=hwnd; @@ -2365,6 +2397,26 @@ LRESULT WINAPI eel_lice_wndproc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lPar return 0; } break; + case WM_DROPFILES: + { + eel_lice_state *ctx=(eel_lice_state*)GetWindowLongPtr(hwnd, GWLP_USERDATA); + if (ctx && wParam) + { + ctx->m_ddrop_files.Empty(true,free); + + HDROP hDrop = (HDROP) wParam; + const int n=DragQueryFile(hDrop,-1,NULL,0); + for (int x=0;xm_ddrop_files.Add(strdup(buf)); + } + DragFinish(hDrop); + } + } + return 0; case WM_MOUSEHWHEEL: case WM_MOUSEWHEEL: { @@ -2780,6 +2832,7 @@ static const char *eel_lice_function_reference = "gfx_roundrect\tx,y,w,h,radius[,antialias]\tDraws a rectangle with rounded corners. \0" "gfx_arc\tx,y,r,ang1,ang2[,antialias]\tDraws an arc of the circle centered at x,y, with ang1/ang2 being specified in radians.\0" "gfx_set\tr[,g,b,a,mode,dest]\tSets gfx_r/gfx_g/gfx_b/gfx_a/gfx_mode, sets gfx_dest if final parameter specified\0" + "gfx_getdropfile\tidx[,#str]\tEnumerates any drag/dropped files. call gfx_dropfile(-1) to clear the list when finished. Returns 1 if idx is valid, 0 if idx is out of range.\0" #ifdef EEL_LICE_WANT_STANDALONE #ifndef EEL_LICE_STANDALONE_NOINITQUIT From 3a2b3edcc954162e61894eb7ddf6db30cd35607c Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 29 May 2018 21:20:01 -0400 Subject: [PATCH 068/144] swell-generic: fix indeterminate checkboxes -- from 6fc72e85 --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 54cc8558..fc19e201 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -1503,7 +1503,7 @@ static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA if (hwnd) { buttonWindowState *s = (buttonWindowState*)hwnd->m_private_data; - return (s->state&3)==2 ? 1 : (s->state&3); + return (s->state&3); } return 0; case BM_GETIMAGE: From cacf93b05e3341f43bc743307ee4da971c60a2c7 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 31 May 2018 14:30:38 -0400 Subject: [PATCH 069/144] swell-generic: fix TPM_NONOTIFY vs TPM_RETURNCMD bug -- from fb451bda --- WDL/swell/swell-menu-generic.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp index 9fc12daa..b286e48e 100644 --- a/WDL/swell/swell-menu-generic.cpp +++ b/WDL/swell/swell-menu-generic.cpp @@ -1128,14 +1128,16 @@ int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND h // if (oldFoc_child) SetFocus(oldFoc); - if (!(flags&TPM_NONOTIFY) && m_trackingRet>0) + if (!(flags&TPM_RETURNCMD) && m_trackingRet>0) SendMessage(hwnd,WM_COMMAND,m_trackingRet,0); if (hwnd) hwnd->Release(); hMenu->Release(); - return m_trackingRet>0?m_trackingRet:0; + if (flags & TPM_RETURNCMD) return m_trackingRet>0?m_trackingRet:0; + + return 1; } From 11bf6f8b5407f784245f94cc191b6fd8dbc88499 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 1 Jun 2018 09:08:30 -0400 Subject: [PATCH 070/144] swell-gdi-lice: clear new memory contexts (since macOS and win32 seem to do this) -- from 4284862d --- WDL/swell/swell-gdi-lice.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp index 6032aff9..3326d9dd 100644 --- a/WDL/swell/swell-gdi-lice.cpp +++ b/WDL/swell/swell-gdi-lice.cpp @@ -266,6 +266,7 @@ HDC SWELL_CreateMemContext(HDC hdc, int w, int h) { LICE_MemBitmap * bm = new LICE_MemBitmap(w,h); if (!bm) return 0; + LICE_Clear(bm,LICE_RGBA(0,0,0,0)); HDC__ *ctx=SWELL_GDP_CTX_NEW(); ctx->surface = bm; From 8d283b7ad532b24db22a7ccf66a4617044f891ef Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 2 Jun 2018 10:40:57 -0400 Subject: [PATCH 071/144] swell-generic: do not set focus for DrawFocusRect -- from c3073e21 --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index fc19e201..17586a88 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -7612,7 +7612,7 @@ void SWELL_DrawFocusRect(HWND hwndPar, RECT *rct, void **handle) h->m_style = WS_CHILD; // using this for top-level will also keep it out of the window list h->Retain(); *handle = h; - ShowWindow(h,SW_SHOW); + ShowWindow(h,SW_SHOWNA); } SetWindowPos(h,HWND_TOP,rct->left,rct->top,rct->right-rct->left,rct->bottom-rct->top,SWP_NOACTIVATE); InvalidateRect(h,NULL,FALSE); From ed00528543b8f509c27030c40dc5c4232d60f07e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 4 Jun 2018 11:17:29 -0400 Subject: [PATCH 072/144] swell-generic: improve some hidden-cursor mouse behaviors - linux: improve mouse behaviors for various knobs -- from 4e755622 --- WDL/swell/swell-generic-gdk.cpp | 2 +- WDL/wingui/virtwnd-slider.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index a87eadd4..bf33e526 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -2297,7 +2297,7 @@ int SWELL_ShowCursor(BOOL bShow) g_swell_mouse_relmode_curpos_y = y1; s_last_cursor = GetCursor(); SetCursor((HCURSOR)gdk_cursor_new_for_display(gdk_display_get_default(),GDK_BLANK_CURSOR)); - g_swell_mouse_relmode=true; + //g_swell_mouse_relmode=true; } if (s_cursor_vis_cnt==0 && bShow) { diff --git a/WDL/wingui/virtwnd-slider.cpp b/WDL/wingui/virtwnd-slider.cpp index db7d9cac..5891e22f 100644 --- a/WDL/wingui/virtwnd-slider.cpp +++ b/WDL/wingui/virtwnd-slider.cpp @@ -629,6 +629,9 @@ void WDL_VirtualSlider::OnPaint(LICE_IBitmap *drawbm, int origin_x, int origin_y static double m_move_offset; static int m_click_pos,m_last_y,m_last_x, m_last_precmode; +#if !defined(_WIN32) && !defined(__APPLE__) +static POINT s_lastmousepos; +#endif int WDL_VirtualSlider::OnMouseDown(int xpos, int ypos) @@ -673,6 +676,9 @@ int WDL_VirtualSlider::OnMouseDown(int xpos, int ypos) m_is_knob = wantKnob; +#if !defined(_WIN32) && !defined(__APPLE__) + GetCursorPos(&s_lastmousepos); +#endif m_last_y=ypos; m_last_x=xpos; m_last_precmode=0; @@ -896,12 +902,17 @@ void WDL_VirtualSlider::OnMoveOrUp(int xpos, int ypos, int isup) if (xpos != m_last_x || ypos != m_last_y) { POINT p; +#if !defined(_WIN32) && !defined(__APPLE__) + p = s_lastmousepos; +#else GetCursorPos(&p); p.x-=(xpos-m_last_x); #ifdef _WIN32 p.y-=(ypos-m_last_y); #else p.y+=(ypos-m_last_y); +#endif + #endif @@ -948,6 +959,9 @@ void WDL_VirtualSlider::OnMoveOrUp(int xpos, int ypos, int isup) { m_last_y = ypos; m_last_x = xpos; +#if !defined(_WIN32) && !defined(__APPLE__) + GetCursorPos(&s_lastmousepos); +#endif } else { From 5a5b5ee998fbafc8bd30a67bcc6f5b97e2d04311 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 5 Jun 2018 10:58:48 -0400 Subject: [PATCH 073/144] swell-generic: groupboxes passthrough mouse messages to parent -- from 4fb0fbf1 --- WDL/swell/swell-wnd-generic.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 17586a88..b5663ef9 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -1631,6 +1631,28 @@ static LRESULT WINAPI groupWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM case WM_SETTEXT: InvalidateRect(hwnd,NULL,TRUE); break; + case WM_LBUTTONDBLCLK: + case WM_LBUTTONDOWN: + case WM_LBUTTONUP: + case WM_MBUTTONDBLCLK: + case WM_MBUTTONDOWN: + case WM_MBUTTONUP: + case WM_RBUTTONDBLCLK: + case WM_RBUTTONDOWN: + case WM_RBUTTONUP: + case WM_MOUSEMOVE: + if (GET_Y_LPARAM(lParam) >= SWELL_UI_SCALE(20)) + { + HWND par = GetParent(hwnd); + if (par) + { + POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; + ClientToScreen(hwnd,&pt); + ScreenToClient(par,&pt); + return SendMessage(par,msg,wParam,MAKELPARAM(pt.x,pt.y)); + } + } + break; } return DefWindowProc(hwnd,msg,wParam,lParam); } From 5ba5466f1514e2db97695b9e874e1b968742fcb9 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 15 Jun 2018 11:17:18 -0400 Subject: [PATCH 074/144] timing.c: various improvements (show meaningful units, do not require timingInit()/timingPrint() calls) -- from bb725b35 --- WDL/timing.c | 104 +++++++++++++++++++++++++++------------------------ WDL/timing.h | 13 +++---- 2 files changed, 61 insertions(+), 56 deletions(-) diff --git a/WDL/timing.c b/WDL/timing.c index c27a64d7..a7d0c45d 100644 --- a/WDL/timing.c +++ b/WDL/timing.c @@ -5,27 +5,35 @@ #include #ifdef _WIN32 #include +#else +#include #endif +#include "wdlcstring.h" +#include "wdltypes.h" + static struct { - __int64 st_time; - __int64 cycles,mint,maxt; - int foo; - int calls; -} timingInfo[64]; + WDL_INT64 st_time; + WDL_INT64 cycles,mint,maxt; + WDL_INT64 calls; +} __wdl_timingInfo[64]; +static int __wdl_timingInfo_reg; -static void rdtsc(__int64 *t) +static void __wdl_timingInfo_gettime(WDL_INT64 *t) { #ifdef _WIN64 +#define TIMING_UNITS "QPC_UNITS" LARGE_INTEGER now; QueryPerformanceCounter(&now); *t = now.QuadPart; #elif !defined(_WIN32) +#define TIMING_UNITS "uSec" struct timeval tm={0,}; gettimeofday(&tm,NULL); - *t = ((__int64)tm.tv_sec)*1000000 + (__int64)tm.tv_usec; + *t = ((WDL_INT64)tm.tv_sec)*1000000 + (WDL_INT64)tm.tv_usec; #else +#define TIMING_UNITS "cycles" __asm { mov esi, t @@ -36,62 +44,62 @@ static void rdtsc(__int64 *t) } #endif } - -void _timingInit(void) -{ - memset(timingInfo,0,sizeof(timingInfo)); -} - -void _timingEnter(int which) -{ - rdtsc(&timingInfo[which].st_time); -} - -void _timingLeave(int which) -{ - __int64 t; - rdtsc(&t); - t -= timingInfo[which].st_time; - if (!timingInfo[which].mint || t < timingInfo[which].mint) timingInfo[which].mint=t?t:1; - if (t > timingInfo[which].maxt) timingInfo[which].maxt=t; - timingInfo[which].cycles += t; - timingInfo[which].calls += 1; -} void _timingPrint(void) { - int x,p=0; - for (x = 0; x < sizeof(timingInfo)/sizeof(timingInfo[0]); x ++) - { + int x,p=0; + for (x = 0; x < (int) (sizeof(__wdl_timingInfo)/sizeof(__wdl_timingInfo[0])); x ++) + { char buf[512]; - if (timingInfo[x].calls) + if (__wdl_timingInfo[x].calls) { p++; - sprintf(buf,"%d: %d calls, %.4f clocks/call (min=%.4f, max=%.4f). %.8f thingies of CPU time spent\n", - x,timingInfo[x].calls,(timingInfo[x].cycles/(double)timingInfo[x].calls), - (double)timingInfo[x].mint,(double)timingInfo[x].maxt, - (double)timingInfo[x].cycles -#if defined(_WIN64) || !defined(_WIN32) - / 1000000.0 -#else - / (2.4*1000.0*1000.0*1000.0) -#endif - + snprintf(buf,sizeof(buf),"wdl_timing: %d: %.0f calls, %.0f " TIMING_UNITS "/call (min=%.0f, max=%.0f). %.0f " TIMING_UNITS " of CPU time spent\n", + x,(double)__wdl_timingInfo[x].calls,(__wdl_timingInfo[x].cycles/(double)__wdl_timingInfo[x].calls), + (double)__wdl_timingInfo[x].mint,(double)__wdl_timingInfo[x].maxt, + (double)__wdl_timingInfo[x].cycles ); #ifdef _WIN32 - OutputDebugString(buf); + OutputDebugStringA(buf); #else printf("%s",buf); #endif } - } + } #ifdef _WIN32 - if (!p) OutputDebugString("no calls to timing lib\n"); + if (!p) OutputDebugStringA("wdl_timing: no calls to timing lib\n"); #else - if (!p) printf("no calls to timing lib\n"); + if (!p) printf("wdl_timing: no calls to timing lib\n"); #endif - - timingInit(); } + +void _timingEnter(int which) +{ + if (!__wdl_timingInfo_reg) + { + __wdl_timingInfo_reg=1; + atexit(_timingPrint); + } + + if (which >= 0 && which < (int) (sizeof(__wdl_timingInfo)/sizeof(__wdl_timingInfo[0]))) + __wdl_timingInfo_gettime(&__wdl_timingInfo[which].st_time); +} + +void _timingLeave(int which) +{ + if (which >= 0 && which < (int) (sizeof(__wdl_timingInfo)/sizeof(__wdl_timingInfo[0]))) + { + WDL_INT64 t; + __wdl_timingInfo_gettime(&t); + t -= __wdl_timingInfo[which].st_time; + if (!__wdl_timingInfo[which].mint || t < __wdl_timingInfo[which].mint) __wdl_timingInfo[which].mint=t?t:1; + if (t > __wdl_timingInfo[which].maxt) __wdl_timingInfo[which].maxt=t; + __wdl_timingInfo[which].cycles += t; + __wdl_timingInfo[which].calls += 1; + } +} + + +#undef TIMING_UNITS #endif diff --git a/WDL/timing.h b/WDL/timing.h index 7960bd4d..e4a4deb7 100644 --- a/WDL/timing.h +++ b/WDL/timing.h @@ -18,26 +18,23 @@ -#if defined(TIMING) && !defined(__alpha) +#if defined(TIMING) #ifdef __cplusplus extern "C" { #endif -void _timingInit(void); -void _timingPrint(void); void _timingEnter(int); void _timingLeave(int); #ifdef __cplusplus } #endif -#define timingPrint() _timingPrint() -#define timingInit() _timingInit() #define timingLeave(x) _timingLeave(x) #define timingEnter(x) _timingEnter(x) #else -#define timingPrint() -#define timingInit() #define timingLeave(x) #define timingEnter(x) #endif -#endif \ No newline at end of file +#define timingPrint() +#define timingInit() + +#endif From 7fb84910c4fa82b5bfa5ebf774370f04a1bd8e29 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 26 Jun 2018 18:02:09 -0400 Subject: [PATCH 075/144] linux makefile compiler improvements, can use: make COMPILER=CLANG or make COMPILER=ICC from c354a05f --- WDL/swell/Makefile | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index 70edaaeb..8ae27625 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -8,23 +8,33 @@ UNAME_S := $(shell uname -s) PKG_CONFIG = pkg-config -CFLAGS = -pipe -fvisibility=hidden -fno-math-errno -fPIC -DPIC -Wall -Wshadow -Wno-unused-function -Wno-multichar -Wno-unused-result +COMPILER=GCC + +CFLAGS = -pipe -fvisibility=hidden -fno-math-errno -fPIC -DPIC -Wall -Wshadow -Wno-unused-function -Wno-multichar CFLAGS += -DSWELL_MAKING_DYLIB ifeq ($(UNAME_S),Darwin) CFLAGS += -Wno-unused-private-field -DSWELL_FORCE_GENERIC DLL_EXT=.dylib - CLANG=1 + COMPILER=CLANG else DLL_EXT=.so endif -ifdef CLANG +ifeq ($(COMPILER),CLANG) CC = clang CXX = clang++ endif +ifeq ($(COMPILER),ICC) + CC = icc + CXX = icpc + CFLAGS += -D__PURE_SYS_C99_HEADERS__ +else + CFLAGS += -Wno-unused-result +endif + ifndef ALLOW_WARNINGS CFLAGS += -Werror endif @@ -41,7 +51,7 @@ ifdef DEBUG CFLAGS += -O0 -g -D_DEBUG else CFLAGS += -O2 -DNDEBUG - ifndef CLANG + ifneq ($(COMPILER),CLANG) CFLAGS += -s endif endif From 3d7ebd4c55c16d9ec9e53d52cb8555f5c06f5178 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 11 Jul 2018 15:00:22 -0400 Subject: [PATCH 076/144] swell-generic: support EnumWindows() -- from 311d417f --- WDL/swell/swell-wnd-generic.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index b5663ef9..1c80e81f 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -662,7 +662,14 @@ void SetWindowPos(HWND hwnd, HWND zorder, int x, int y, int cx, int cy, int flag BOOL EnumWindows(BOOL (*proc)(HWND, LPARAM), LPARAM lp) { - return FALSE; + HWND h = SWELL_topwindows; + if (!proc) return FALSE; + while (h) + { + if (!proc(h,lp)) return FALSE; + h = h->m_next; + } + return TRUE; } HWND GetWindow(HWND hwnd, int what) From 502e352912b7b216bb3c4f776a41700bf48a62cc Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 11 Jul 2018 15:07:34 -0400 Subject: [PATCH 077/144] swell-generic: improve FindWindowEx() -- from b20837d1 --- WDL/swell/swell-wnd-generic.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 1c80e81f..b1f24593 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -7179,27 +7179,20 @@ BOOL ScrollWindow(HWND hwnd, int xamt, int yamt, const RECT *lpRect, const RECT HWND FindWindowEx(HWND par, HWND lastw, const char *classname, const char *title) { - if (!par&&!lastw) return NULL; // need to implement this modes - HWND h=lastw?GetWindow(lastw,GW_HWNDNEXT):GetWindow(par,GW_CHILD); + HWND h=lastw?GetWindow(lastw,GW_HWNDNEXT):par?GetWindow(par,GW_CHILD):SWELL_topwindows; while (h) { bool isOk=true; - if (title) + if (title && strcmp(title,h->m_title.Get())) isOk=false; + else if (classname) { - char buf[512]; - buf[0]=0; - GetWindowText(h,buf,sizeof(buf)); - if (strcmp(title,buf)) isOk=false; - } - if (classname) - { - // todo: other classname translations + if (!h->m_classname || strcmp(classname,h->m_classname)) isOk=false; } if (isOk) return h; h=GetWindow(h,GW_HWNDNEXT); } - return h; + return NULL; } From df6b71b39b7a128e238f0a3c1d50e936791b6374 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 11 Jul 2018 15:15:04 -0400 Subject: [PATCH 078/144] swell-generic: fix some cornercase behaviors for ListView_GetItem() -- from ba85b518 --- WDL/swell/swell-wnd-generic.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index b1f24593..1ce6a9e9 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -5885,11 +5885,15 @@ bool ListView_GetItem(HWND h, LVITEM *item) if (item->mask & LVIF_STATE) { - item->state = lvs->get_sel(item->iItem) ? LVIS_SELECTED : 0; - if (lvs->m_selitem == item->iItem) item->state |= LVIS_FOCUSED; - SWELL_ListView_Row *row = lvs->m_data.Get(item->iItem); - if (row) - item->state |= INDEXTOSTATEIMAGEMASK(row->m_imageidx); + item->state = 0; + if ((item->stateMask & LVIS_SELECTED) && lvs->get_sel(item->iItem)) item->state |= LVIS_SELECTED; + if ((item->stateMask & LVIS_FOCUSED) && lvs->m_selitem == item->iItem) item->state |= LVIS_FOCUSED; + if (item->stateMask & 0xff0000) + { + SWELL_ListView_Row *row = lvs->m_data.Get(item->iItem); + if (row) + item->state |= INDEXTOSTATEIMAGEMASK(row->m_imageidx); + } } return true; From 66fc8ebef66ff199f2baeec29e80273577134aaf Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 14 Jul 2018 17:29:04 -0400 Subject: [PATCH 079/144] timing.c patches from Tale -- from 98895945 --- WDL/timing.c | 25 ++++++++++++++++++++++--- WDL/timing.h | 10 ++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/WDL/timing.c b/WDL/timing.c index a7d0c45d..90ccb78e 100644 --- a/WDL/timing.c +++ b/WDL/timing.c @@ -10,7 +10,10 @@ #endif #include "wdlcstring.h" -#include "wdltypes.h" + +#if defined(__APPLE__) && defined(__OBJC__) +#import +#endif static struct { WDL_INT64 st_time; @@ -61,16 +64,22 @@ void _timingPrint(void) ); #ifdef _WIN32 OutputDebugStringA(buf); +#elif defined(__APPLE__) && defined(__OBJC__) + NSLog(@"%s",buf); #else printf("%s",buf); #endif } } + if (!p) #ifdef _WIN32 - if (!p) OutputDebugStringA("wdl_timing: no calls to timing lib\n"); + OutputDebugString( +#elif defined(__APPLE__) && defined(__OBJC__) + NSLog(@ #else - if (!p) printf("wdl_timing: no calls to timing lib\n"); + printf( #endif + "wdl_timing: no calls to timing lib\n"); } void _timingEnter(int which) @@ -99,6 +108,16 @@ void _timingLeave(int which) } } +WDL_INT64 _timingQuery(int which, WDL_INT64* cycles) +{ + if (__wdl_timingInfo[which].calls && cycles) + { + cycles[0] = __wdl_timingInfo[which].cycles; + cycles[1] = __wdl_timingInfo[which].mint; + cycles[2] = __wdl_timingInfo[which].maxt; + } + return __wdl_timingInfo[which].calls; +} #undef TIMING_UNITS diff --git a/WDL/timing.h b/WDL/timing.h index e4a4deb7..4d11004e 100644 --- a/WDL/timing.h +++ b/WDL/timing.h @@ -3,10 +3,8 @@ this is based on some public domain Pentium RDTSC timing code from usenet in 1996. - To enable this, your app must #define TIMING, include timing.h, call timingInit(), then timingEnter(x)/timingLeave(x) a bunch - of times (where x is 0-64), then timingPrint at the end. - - on timingPrint(), C:\\timings.txt will be overwritten. + To enable this, your app must #define TIMING, include timing.h, and call timingEnter(x)/timingLeave(x) a bunch + of times (where x is 0..63). */ @@ -17,6 +15,7 @@ //#define TIMING +#include "wdltypes.h" #if defined(TIMING) #ifdef __cplusplus @@ -24,14 +23,17 @@ extern "C" { #endif void _timingEnter(int); void _timingLeave(int); +WDL_INT64 _timingQuery(int, WDL_INT64*); #ifdef __cplusplus } #endif #define timingLeave(x) _timingLeave(x) #define timingEnter(x) _timingEnter(x) +#define timingQuery(x,y) _timingQuery(x,y) #else #define timingLeave(x) #define timingEnter(x) +#define timingQuery(x,y) (0) #endif #define timingPrint() From 2c0abc691788719f4a0c05013e37bbab37cba8d6 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 16 Jul 2018 16:09:10 -0400 Subject: [PATCH 080/144] swell: support loading libSwell.colortheme from custom swell-configuration path -- from e2fc9f4e --- WDL/swell/swell-gdi-generic.cpp | 29 ++++++++++++++++++----------- WDL/swell/swell.cpp | 15 +++++++++++++-- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/WDL/swell/swell-gdi-generic.cpp b/WDL/swell/swell-gdi-generic.cpp index 0c9b73b4..d8982090 100644 --- a/WDL/swell/swell-gdi-generic.cpp +++ b/WDL/swell/swell-gdi-generic.cpp @@ -689,21 +689,14 @@ return 0; } #else -// load color theme -class swellColorThemeLoader +void swell_load_color_theme(const char *fn) { -public: - swellColorThemeLoader() + FILE *fp = fopen(fn,"r"); + if (fp) { - char buf[1024]; - GetModuleFileName(NULL,buf,sizeof(buf)); - WDL_remove_filepart(buf); - lstrcatn(buf,"/libSwell.colortheme",sizeof(buf)); - FILE *fp = fopen(buf,"r"); - if (!fp) return; - swell_colortheme load; memset(&load,-1,sizeof(load)); + char buf[1024]; for (;;) { @@ -761,6 +754,20 @@ SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb) fclose(fp); } +} + +// load color theme +class swellColorThemeLoader +{ +public: + swellColorThemeLoader() + { + char buf[1024]; + GetModuleFileName(NULL,buf,sizeof(buf)); + WDL_remove_filepart(buf); + lstrcatn(buf,"/libSwell.colortheme",sizeof(buf)); + swell_load_color_theme(buf); + } }; swellColorThemeLoader g_swell_themeloader; diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 07ed05d4..db85cb91 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -36,7 +36,6 @@ #include "swell-internal.h" - #ifdef SWELL_TARGET_OSX #include #endif @@ -56,6 +55,7 @@ #include "../wdlatomic.h" #include "../mutex.h" #include "../assocarray.h" +#include "../wdlcstring.h" void Sleep(int ms) { @@ -1004,7 +1004,7 @@ void *SWELL_ExtendedAPI(const char *key, void *v) g_swell_defini = v ? strdup((const char *)v) : NULL; #ifndef SWELL_TARGET_OSX - char buf[128]; + char buf[1024]; GetPrivateProfileString(".swell","max_open_files","",buf,sizeof(buf),""); if (!buf[0]) WritePrivateProfileString(".swell","max_open_files","auto // (default is max of default or 16384)",""); @@ -1043,6 +1043,17 @@ void *SWELL_ExtendedAPI(const char *key, void *v) { WritePrivateProfileString(".swell","ui_scale","1.0 // scales the sizes in libSwell.colortheme",""); } + if (g_swell_defini) + { + void swell_load_color_theme(const char *fn); + lstrcpyn_safe(buf,g_swell_defini,sizeof(buf)); + WDL_remove_filepart(buf); + if (buf[0]) + { + lstrcatn(buf,"/libSwell.colortheme",sizeof(buf)); + swell_load_color_theme(buf); + } + } #endif } else if (!strcmp(key,"FONTPANGRAM")) From ce4af3a4255de52ddbe010ca1c668e0052a82ff2 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 17 Jul 2018 15:31:26 -0400 Subject: [PATCH 081/144] swell-generic: fix mouseover menu navigation -- from 09a1d924 --- WDL/swell/swell-menu-generic.cpp | 2 +- WDL/swell/swell-wnd-generic.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp index b286e48e..4b55612b 100644 --- a/WDL/swell/swell-menu-generic.cpp +++ b/WDL/swell/swell-menu-generic.cpp @@ -1137,7 +1137,7 @@ int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND h if (flags & TPM_RETURNCMD) return m_trackingRet>0?m_trackingRet:0; - return 1; + return resvd!=0xbeef || m_trackingRet>0; } diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 1ce6a9e9..5cdb28f4 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6618,7 +6618,7 @@ static void runMenuBar(HWND hwnd, HMENU__ *menu, int x, const RECT *use_r) for (;;) { InvalidateRect(hwnd,&mbr,FALSE); - if (TrackPopupMenu(inf->hSubMenu,0,r.left,r.bottom,0,hwnd,NULL) || menu->sel_vis == x) break; + if (TrackPopupMenu(inf->hSubMenu,0,r.left,r.bottom,0xbeef,hwnd,NULL) || menu->sel_vis == x) break; x = menu->sel_vis; inf = menu->items.Get(x); From 738f90da5ce7a56d4baac7e4b3f3ec9881eea214 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 17 Jul 2018 15:57:48 -0400 Subject: [PATCH 082/144] swell-generic: fix CB_ADDSTRING with CBS_SORT causing incorrect selection state -- from 39f22126 --- WDL/swell/swell-wnd-generic.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 5cdb28f4..9588066e 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -3177,6 +3177,7 @@ static LRESULT WINAPI comboWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM // find position of insert for wParam bool m; int idx = s->items.LowerBound(r,&m,__SWELL_ComboBoxInternalState_rec::cmp); + if (s->selidx >= idx) s->selidx++; s->items.Insert(idx,r); return idx; } From d594771edd12918994252ec64b512df766d3d380 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 19 Jul 2018 09:41:38 -0400 Subject: [PATCH 083/144] swell-generic: select listview item on right click -- from 75160de5 --- WDL/swell/swell-wnd-generic.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 9588066e..a98e0636 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -3848,6 +3848,17 @@ static LRESULT listViewWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa case WM_RBUTTONDOWN: if (lvs && lvs->m_last_row_height>0 && !lvs->m_is_listbox) { + LVHITTESTINFO inf = { { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }, }; + const int row = ListView_HitTest(hwnd, &inf); + const int n = ListView_GetItemCount(hwnd); + if (row>=0 && rowm_id,NM_RCLICK},0,0,0,}; SendMessage(GetParent(hwnd),WM_NOTIFY,hwnd->m_id,(LPARAM)&nm); } From 8bc807cf1d51d52112a5955349c5119b05c5e90e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 19 Jul 2018 16:18:06 -0400 Subject: [PATCH 084/144] swell-generic: only select listview item on right click if it was not previously selected -- from d84c07ba --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index a98e0636..bc95591e 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -3851,7 +3851,7 @@ static LRESULT listViewWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa LVHITTESTINFO inf = { { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }, }; const int row = ListView_HitTest(hwnd, &inf); const int n = ListView_GetItemCount(hwnd); - if (row>=0 && row=0 && row Date: Fri, 20 Jul 2018 09:05:03 -0400 Subject: [PATCH 085/144] swell-generic: fix support for launching applications with parameters -- from 85bc7fd2 --- WDL/swell/swell-wnd-generic.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index bc95591e..edc7a9e1 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -7582,8 +7582,16 @@ BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const } else { - argv[0] = xdg; - argv[1] = content1; // default to xdg-open for whatever else + if (content2 && *content2) + { + argv[0] = content1; + argv[1] = content2; + } + else + { + argv[0] = xdg; + argv[1] = content1; // default to xdg-open for whatever else + } } if (fork() == 0) @@ -7593,7 +7601,7 @@ BOOL ShellExecute(HWND hwndDlg, const char *action, const char *content1, const exit(0); // if execv fails for some reason } free(tmp); - return FALSE; + return TRUE; } From bf8bc70ffedd9b49a45d82dc13f5ee2d18989494 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 22 Jul 2018 13:33:56 -0400 Subject: [PATCH 086/144] swell-generic: draw blank lines in multiline labels -- from 006f0ee0 --- WDL/swell/swell-wnd-generic.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index edc7a9e1..5f0915b8 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -3105,10 +3105,8 @@ static LRESULT WINAPI labelWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM { int post=0, lb=swell_getLineLength(buf+loffs, &post, r.right, ps.hdc); if (lb>0) - { DrawText(ps.hdc,buf+loffs,lb,&r,DT_TOP|DT_SINGLELINE|DT_LEFT); - r.top += line_h; - } + r.top += line_h; loffs+=lb+post; } buf = NULL; From a5c377811877f5b5abb7525d00f2ca83a8b65155 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 22 Jul 2018 13:44:57 -0400 Subject: [PATCH 087/144] swell-generic: blinking edit cursor does not affect scrollbar measurement -- from eaa691a5 --- WDL/swell/swell-wnd-generic.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 5f0915b8..6399bb21 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -2690,7 +2690,8 @@ static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM SetBkMode(ps.hdc,TRANSPARENT); r.left+=2 - es->scroll_x; r.right-=2; - const int cursor_pos = (focused && es->cursor_state) ? WDL_utf8_charpos_to_bytepos(hwnd->m_title.Get(),es->cursor_pos) : -1; + const bool do_cursor = es->cursor_state!=0; + const int cursor_pos = focused ? WDL_utf8_charpos_to_bytepos(hwnd->m_title.Get(),es->cursor_pos) : -1; const int sel1 = es->sel1>=0 && focused ? WDL_utf8_charpos_to_bytepos(hwnd->m_title.Get(),es->sel1) : -1; const int sel2 = es->sel2>=0 && focused ? WDL_utf8_charpos_to_bytepos(hwnd->m_title.Get(),es->sel2) : -1; @@ -2754,7 +2755,7 @@ static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM if (vis) { int wid = editControlPaintLine(ps.hdc,buf,lb, - (cursor_pos >= bytepos && cursor_pos <= bytepos + lb) ? cursor_pos - bytepos : -1, + (do_cursor && cursor_pos >= bytepos && cursor_pos <= bytepos + lb) ? cursor_pos - bytepos : -1, sel1 >= 0 ? (sel1 - bytepos) : -1, sel2 >= 0 ? (sel2 - bytepos) : -1, &r, DT_TOP); From 7bac7cb2d3fe217f7e1d6741706a9251192cf21c Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 22 Jul 2018 13:56:20 -0400 Subject: [PATCH 088/144] swell-generic: fix multi-line edit field hit testing corner case -- from b421568d --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 6399bb21..38793ea0 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -1798,7 +1798,7 @@ static bool editGetCharPos(HDC hdc, const char *str, int singleline_len, int cha } str += lb+pskip; bytepos -= lb+pskip; - ypos += line_h; + if (*str || (pskip>0 && str[-1] == '\n')) ypos += line_h; } pt->x=0; pt->y=ypos; From f41783e34203c27245a0b3a4e0af9ead08da863a Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 24 Jul 2018 10:34:43 -0400 Subject: [PATCH 089/144] swell-generic: always use borderless overrideredirect for top level windows with a plain WS_CHILD style set (tooltips, menus) -- from 8557e4f2 --- WDL/swell/swell-generic-gdk.cpp | 2 +- WDL/swell/swell-menu-generic.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index bf33e526..37c58343 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -489,7 +489,7 @@ void swell_oswindow_manage(HWND hwnd, bool wantfocus) if (!(hwnd->m_style & WS_CAPTION)) { - if ((!hwnd->m_classname || strcmp(hwnd->m_classname,"__SWELL_MENU")) && !(gdk_options&OPTION_BORDERLESS_OVERRIDEREDIRECT)) + if (hwnd->m_style != WS_CHILD && !(gdk_options&OPTION_BORDERLESS_OVERRIDEREDIRECT)) { if (transient_for) gdk_window_set_transient_for(hwnd->m_oswindow,transient_for); diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp index 4b55612b..c88df4b7 100644 --- a/WDL/swell/swell-menu-generic.cpp +++ b/WDL/swell/swell-menu-generic.cpp @@ -1019,6 +1019,7 @@ static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM else { hh = new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL, hwnd); + hh->m_style = WS_CHILD; SetProp(hh,"SWELL_MenuOwner",GetProp(hwnd,"SWELL_MenuOwner")); } @@ -1105,6 +1106,7 @@ int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND h hMenu->sel_vis=-1; HWND hh=new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL, hwnd); + hh->m_style = WS_CHILD; submenuWndProc(hh,WM_CREATE,0,(LPARAM)hMenu); From 3759a0fb17870827e8f8e1c6c96c1ff6197e523b Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 24 Jul 2018 10:38:40 -0400 Subject: [PATCH 090/144] swell-generic: remove gdk_borderless_override_redirect option, add new gdk_borderless_mode option -- from 3b9562d9 --- WDL/swell/swell-generic-gdk.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index 37c58343..ed76eff3 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -112,6 +112,7 @@ static int gdk_options; #define OPTION_KEEP_OWNED_ABOVE 1 #define OPTION_OWNED_TASKLIST 2 #define OPTION_BORDERLESS_OVERRIDEREDIRECT 4 +#define OPTION_BORDERLESS_DIALOG 8 static HWND s_ddrop_hwnd; static POINT s_ddrop_pt; @@ -420,7 +421,7 @@ static void init_options() { if (!gdk_options) { - const char *wmname = gdk_x11_screen_get_window_manager_name(gdk_screen_get_default ()); + //const char *wmname = gdk_x11_screen_get_window_manager_name(gdk_screen_get_default ()); gdk_options = 0x40000000; @@ -430,8 +431,12 @@ static void init_options() if (swell_gdk_option("gdk_owned_windows_in_tasklist", "auto (default is 0)",0)) gdk_options|=OPTION_OWNED_TASKLIST; - if (swell_gdk_option("gdk_borderless_are_override_redirect", "auto (default is 0)", wmname && !stricmp(wmname,"i3"))) - gdk_options|=OPTION_BORDERLESS_OVERRIDEREDIRECT; + switch (swell_gdk_option("gdk_borderless_window_mode", "auto (default is 1=dialog hint. 2=override redirect. 0=normal hint)", 1)) + { + case 1: gdk_options|=OPTION_BORDERLESS_DIALOG; break; + case 2: gdk_options|=OPTION_BORDERLESS_OVERRIDEREDIRECT; break; + default: break; + } } } @@ -493,7 +498,7 @@ void swell_oswindow_manage(HWND hwnd, bool wantfocus) { if (transient_for) gdk_window_set_transient_for(hwnd->m_oswindow,transient_for); - gdk_window_set_type_hint(hwnd->m_oswindow, GDK_WINDOW_TYPE_HINT_NORMAL); + gdk_window_set_type_hint(hwnd->m_oswindow, (gdk_options&OPTION_BORDERLESS_DIALOG) ? GDK_WINDOW_TYPE_HINT_DIALOG : GDK_WINDOW_TYPE_HINT_NORMAL); gdk_window_set_decorations(hwnd->m_oswindow,(GdkWMDecoration) 0); } else From 9baed68a080e32be51a26181b684e6691fb311f3 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 24 Jul 2018 11:48:28 -0400 Subject: [PATCH 091/144] swell-generic: labels and buttons obey WM_CTLCOLORSTATIC text-color choices -- from 5b9be80b --- WDL/swell/swell-wnd-generic.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 38793ea0..5c08938a 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -1360,7 +1360,6 @@ static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA buttonWindowState *s = (buttonWindowState*)hwnd->m_private_data; RECT r; GetClientRect(hwnd,&r); - paintDialogBackground(hwnd,&r,ps.hdc); bool pressed = GetCapture()==hwnd; @@ -1369,6 +1368,8 @@ static LRESULT WINAPI buttonWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARA g_swell_ctheme.button_text_disabled); SetBkMode(ps.hdc,TRANSPARENT); + paintDialogBackground(hwnd,&r,ps.hdc); + int f=DT_VCENTER; int sf = (hwnd->m_style & 0xf); if (sf == BS_OWNERDRAW) @@ -3085,13 +3086,13 @@ static LRESULT WINAPI labelWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM RECT r; GetClientRect(hwnd,&r); - paintDialogBackground(hwnd,&r,ps.hdc); - SetTextColor(ps.hdc, hwnd->m_enabled ? g_swell_ctheme.label_text : g_swell_ctheme.label_text_disabled); SetBkMode(ps.hdc,TRANSPARENT); + paintDialogBackground(hwnd,&r,ps.hdc); + const char *buf = hwnd->m_title.Get(); if (buf && buf[0]) { From 3a629e1cb538dd5c7236564aa11cdb39226d5f17 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 24 Jul 2018 14:47:54 -0400 Subject: [PATCH 092/144] swell-generic: default font fallback logic goes to Liberation -- from 0791cc79 --- WDL/swell/swell-gdi-lice.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp index 3326d9dd..00604a0e 100644 --- a/WDL/swell/swell-gdi-lice.cpp +++ b/WDL/swell/swell-gdi-lice.cpp @@ -388,8 +388,8 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, { static const char *ent[2] = { "ft_font_fallback", "ft_font_fallback_fixedwidth" }; static const char *def[2] = { - "// Cantarell FreeSans DejaVuSans NotoSans LiberationSans Oxygen Arial Verdana", - "// FreeMono DejaVuSansMono NotoMono OxygenMono LiberationMono Courier" + "// LiberationSans Cantarell FreeSans DejaVuSans NotoSans Oxygen Arial Verdana", + "// LiberationMono FreeMono DejaVuSansMono NotoMono OxygenMono Courier" }; char tmp[1024]; GetPrivateProfileString(".swell",ent[wl],"",tmp,sizeof(tmp),""); From 0498714708cb70bc12cf2cf3e28779ebc1e81fb8 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 24 Jul 2018 14:55:22 -0400 Subject: [PATCH 093/144] swell-generic: improve listview left margins -- from 859da947 --- WDL/swell/swell-wnd-generic.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 5c08938a..cf0f2230 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -4531,13 +4531,18 @@ static LRESULT listViewWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa { if (ncols > 0) { - ar.right = ar.left + cols[col].xwid - 3; + ar.right = ar.left + cols[col].xwid - SWELL_UI_SCALE(3); xpos += cols[col].xwid; } else ar.right = cr.right; if (ar.right > ar.left) + { + const int adj = (ar.right-ar.left)/16; + const int maxadj = SWELL_UI_SCALE(4); + ar.left += wdl_min(adj,maxadj); DrawText(ps.hdc,str,-1,&ar,DT_LEFT|DT_VCENTER|DT_SINGLELINE|DT_NOPREFIX); + } } } ypos += row_height; From 9164b6134f570843c7f0704e95f4be508cc76b97 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 24 Jul 2018 15:50:35 -0400 Subject: [PATCH 094/144] swell-generic: simplify menu style initialization -- from 3b1a88a9 --- WDL/swell/swell-menu-generic.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp index c88df4b7..ffc8fa05 100644 --- a/WDL/swell/swell-menu-generic.cpp +++ b/WDL/swell/swell-menu-generic.cpp @@ -400,6 +400,7 @@ static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM { case WM_CREATE: hwnd->m_classname = "__SWELL_MENU"; + hwnd->m_style = WS_CHILD; m_trackingMenus.Add(hwnd); SetWindowLongPtr(hwnd,GWLP_USERDATA,lParam); @@ -497,7 +498,6 @@ static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM hwnd->m_extra[1] = 0; // &1=allow scroll flag (set from paint), &2=force scroll down (if sel_vis is offscreen positive) } - SetWindowLong(hwnd,GWL_STYLE,GetWindowLong(hwnd,GWL_STYLE)&~WS_CAPTION); ShowWindow(hwnd,SW_SHOW); SetFocus(hwnd); SetTimer(hwnd,1,100,NULL); @@ -1019,7 +1019,6 @@ static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM else { hh = new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL, hwnd); - hh->m_style = WS_CHILD; SetProp(hh,"SWELL_MenuOwner",GetProp(hwnd,"SWELL_MenuOwner")); } @@ -1106,7 +1105,6 @@ int TrackPopupMenu(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND h hMenu->sel_vis=-1; HWND hh=new HWND__(NULL,0,NULL,"menu",false,submenuWndProc,NULL, hwnd); - hh->m_style = WS_CHILD; submenuWndProc(hh,WM_CREATE,0,(LPARAM)hMenu); From d9619efe0f551b1bacd8957318fa783b8aa6d100 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 23 Jul 2018 18:33:18 -0400 Subject: [PATCH 095/144] swell-generic: ListView_GetSubItemRect etc clamp Y position to sane values -- from f2e5bc05 --- WDL/swell/swell-wnd-generic.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index cf0f2230..41f66379 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6180,6 +6180,8 @@ bool ListView_GetSubItemRect(HWND h, int item, int subitem, int code, RECT *r) } } + if (r->top < -64-lvs->m_last_row_height) r->top = -64 - lvs->m_last_row_height; + if (r->top > cr.bottom+64) r->top = cr.bottom+64; r->bottom = r->top + lvs->m_last_row_height; From 8d38d402e555c51b62034f89b27e9f8e94f150ab Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 27 Jul 2018 15:30:42 -0400 Subject: [PATCH 096/144] swell-generic: if ui_scale set to non-1.0, override any x11 scaling + linux: override any x11 scaling if ui_scale= set in reaper.ini -- from e9b29aed --- WDL/swell/swell-generic-gdk.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index ed76eff3..075a6202 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -462,6 +462,27 @@ void swell_oswindow_manage(HWND hwnd, bool wantfocus) if (swell_initwindowsys()) { init_options(); + + #if SWELL_TARGET_GDK == 3 + // would be nice to be able to query the dpi scaling, and override + // g_swell_ui_scale in that case... + static bool scale_check; + if (!scale_check) + { + scale_check=true; + if (g_swell_ui_scale != 256) + { + GdkDisplay *gdkdisp = gdk_display_get_default(); + if (gdkdisp) + { + void (*p)(GdkDisplay*, gint); + *(void **)&p = dlsym(RTLD_DEFAULT,"gdk_x11_display_set_window_scale"); + if (p) p(gdkdisp,1); + } + } + } + #endif + SWELL_OSWINDOW transient_for=NULL; if (hwnd->m_owner && (gdk_options&OPTION_KEEP_OWNED_ABOVE)) { From 5388605c7025cc0184c4cf4f7e461b540ce6550e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 27 Jul 2018 15:42:24 -0400 Subject: [PATCH 097/144] swell-generic: system hidpi detection, can disable using ui_scale_auto=0 -- from f6a9ccba + 7521d386 + 7361060 --- WDL/swell/swell-generic-gdk.cpp | 60 ++++++++++++++++++++++----------- WDL/swell/swell-internal.h | 1 + WDL/swell/swell.cpp | 46 ++++++++++++++++++------- 3 files changed, 75 insertions(+), 32 deletions(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index 075a6202..cf7b1a6a 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -463,26 +463,6 @@ void swell_oswindow_manage(HWND hwnd, bool wantfocus) { init_options(); - #if SWELL_TARGET_GDK == 3 - // would be nice to be able to query the dpi scaling, and override - // g_swell_ui_scale in that case... - static bool scale_check; - if (!scale_check) - { - scale_check=true; - if (g_swell_ui_scale != 256) - { - GdkDisplay *gdkdisp = gdk_display_get_default(); - if (gdkdisp) - { - void (*p)(GdkDisplay*, gint); - *(void **)&p = dlsym(RTLD_DEFAULT,"gdk_x11_display_set_window_scale"); - if (p) p(gdkdisp,1); - } - } - } - #endif - SWELL_OSWINDOW transient_for=NULL; if (hwnd->m_owner && (gdk_options&OPTION_KEEP_OWNED_ABOVE)) { @@ -2445,6 +2425,46 @@ int SWELL_KeyToASCII(int wParam, int lParam, int *newflags) return 0; } +void swell_scaling_init(bool no_auto_hidpi) +{ + #if SWELL_TARGET_GDK == 3 + + if (!no_auto_hidpi && g_swell_ui_scale == 256) + { + int (*gsf)(void*); + void * (*gpm)(GdkDisplay *); + *(void **)&gsf = dlsym(RTLD_DEFAULT,"gdk_monitor_get_scale_factor"); + *(void **)&gpm = dlsym(RTLD_DEFAULT,"gdk_display_get_primary_monitor"); + + if (gpm && gsf) + { + GdkDisplay *gdkdisp = gdk_display_get_default(); + if (gdkdisp) + { + void *m = gpm(gdkdisp); + if (m) + { + int sf = gsf(m); + if (sf > 1 && sf < 8) + g_swell_ui_scale = sf*256; + } + } + } + } + + if (g_swell_ui_scale != 256) + { + GdkDisplay *gdkdisp = gdk_display_get_default(); + if (gdkdisp) + { + void (*p)(GdkDisplay*, gint); + *(void **)&p = dlsym(RTLD_DEFAULT,"gdk_x11_display_set_window_scale"); + if (p) p(gdkdisp,1); + } + } + #endif +} + #endif #endif diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h index 49108c8f..429fc84f 100644 --- a/WDL/swell/swell-internal.h +++ b/WDL/swell/swell-internal.h @@ -1089,6 +1089,7 @@ SWELL_GENERIC_THEMEDEFS(__def_theme_ent,__def_theme_ent_fb) }; #define SWELL_UI_SCALE(x) (((x)*g_swell_ui_scale)/256) +void swell_scaling_init(bool no_auto_hidpi); extern int g_swell_ui_scale; extern swell_colortheme g_swell_ctheme; extern const char *g_swell_deffont_face; diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index db85cb91..6c3d95e8 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -1027,15 +1027,24 @@ void *SWELL_ExtendedAPI(const char *key, void *v) #endif #ifdef SWELL_TARGET_GDK + if (g_swell_defini) + { + void swell_load_color_theme(const char *fn); + lstrcpyn_safe(buf,g_swell_defini,sizeof(buf)); + WDL_remove_filepart(buf); + if (buf[0]) + { + lstrcatn(buf,"/libSwell.colortheme",sizeof(buf)); + swell_load_color_theme(buf); + } + } + GetPrivateProfileString(".swell","ui_scale","",buf,sizeof(buf),""); if (buf[0]) { double sc = atof(buf); if (sc > 0.01 && sc < 10.0 && sc != 1.0) { - #define __scale(x,c) g_swell_ctheme.x = (int) (g_swell_ctheme.x * sc + 0.5); - SWELL_GENERIC_THEMESIZEDEFS(__scale,__scale) - #undef __scale g_swell_ui_scale = (int) (256 * sc + 0.5); } } @@ -1043,16 +1052,29 @@ void *SWELL_ExtendedAPI(const char *key, void *v) { WritePrivateProfileString(".swell","ui_scale","1.0 // scales the sizes in libSwell.colortheme",""); } - if (g_swell_defini) + + bool no_auto_hidpi=false; + GetPrivateProfileString(".swell","ui_scale_auto","",buf,sizeof(buf),""); + if (buf[0]) { - void swell_load_color_theme(const char *fn); - lstrcpyn_safe(buf,g_swell_defini,sizeof(buf)); - WDL_remove_filepart(buf); - if (buf[0]) - { - lstrcatn(buf,"/libSwell.colortheme",sizeof(buf)); - swell_load_color_theme(buf); - } + const char *p = buf; + while (*p == ' ') p++; + if (*p == '0' && atoi(p) == 0) + no_auto_hidpi=true; + } + else + { + WritePrivateProfileString(".swell","ui_scale_auto","1 // set to 0 to disable system DPI detection (only used when ui_scale=1)",""); + } + + swell_scaling_init(no_auto_hidpi); + + if (g_swell_ui_scale != 256) + { + const double sc = g_swell_ui_scale * (1.0 / 256.0); + #define __scale(x,c) g_swell_ctheme.x = (int) (g_swell_ctheme.x * sc + 0.5); + SWELL_GENERIC_THEMESIZEDEFS(__scale,__scale) + #undef __scale } #endif } From 2e1762442f52103880635cbb382b249f5fd76a88 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 27 Jul 2018 17:52:20 -0400 Subject: [PATCH 098/144] eel_lice: on swell-generic, expose UI scaling as retina -- from a45681b0 --- WDL/eel2/eel_lice.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index 08131451..d4bf8318 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -1763,6 +1763,9 @@ int eel_lice_state::setup_frame(HWND hwnd, RECT r, int _mouse_x, int _mouse_y) if (dpi != 96) *m_gfx_ext_retina = dpi / 96.0; } + #else + int r = SWELL_GetScaling256(); + if (r > 256) *m_gfx_ext_retina = r/256.0; #endif #endif } From 283f01c77aa0683f467d7c548ce09a86d58533c0 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 28 Jul 2018 11:42:07 -0400 Subject: [PATCH 099/144] swell-gdk: support Extended('activate_app') message -- from 93850750 --- WDL/swell/swell-generic-gdk.cpp | 9 +++++++++ WDL/swell/swell.cpp | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index cf7b1a6a..a7b415c2 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -168,6 +168,15 @@ static void on_activate(guint32 ftime) s_force_window_time = 0; } +void swell_gdk_reactivate_app(void) +{ + if (swell_app_is_inactive) + { + SWELL_focused_oswindow=NULL; + on_activate(GDK_CURRENT_TIME); + } +} + static void on_deactivate() { swell_app_is_inactive=true; diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 6c3d95e8..2ea433c8 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -1088,6 +1088,13 @@ void *SWELL_ExtendedAPI(const char *key, void *v) int swell_fullscreenWindow(HWND, BOOL); return (void*)(INT_PTR)swell_fullscreenWindow((HWND)v, key[0] != '-'); } +#endif +#ifdef SWELL_TARGET_GDK + else if (!strcmp(key,"activate_app")) + { + void swell_gdk_reactivate_app(void); + swell_gdk_reactivate_app(); + } #endif return NULL; } From b0b250874ec32b2d1de05302dcd2ca589d9d12ab Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 27 Jul 2018 22:06:24 -0400 Subject: [PATCH 100/144] add setthreadname.h -- from eea75ddd + efcdb48d --- WDL/setthreadname.h | 83 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 WDL/setthreadname.h diff --git a/WDL/setthreadname.h b/WDL/setthreadname.h new file mode 100644 index 00000000..996d0859 --- /dev/null +++ b/WDL/setthreadname.h @@ -0,0 +1,83 @@ +#ifndef _WDL_SETTHREADNAME_H_ +#define _WDL_SETTHREADNAME_H_ + +#include "wdltypes.h" + +#if defined(_WIN32) && (defined(_DEBUG) || defined(WDL_SETTHREADNAME_WIN32_RELEASE)) +// thread names only work on win32 when running in a debugger, so they are not enabled +// by default for release builds (defined WDL_SETTHREADNAME_WIN32_RELEASE if you wish to use +// them) + +#pragma pack(push,8) +typedef struct tagTHREADNAME_INFO +{ + DWORD dwType; // Must be 0x1000. + LPCSTR szName; // Pointer to name (in user addr space). + DWORD dwThreadID; // Thread ID (-1=caller thread). + DWORD dwFlags; // Reserved for future use, must be zero. +} THREADNAME_INFO; +#pragma pack(pop) + +static void WDL_SetThreadName(const char* threadName) { + const DWORD MS_VC_EXCEPTION = 0x406D1388; + THREADNAME_INFO info; + info.dwType = 0x1000; + info.szName = threadName; + info.dwThreadID = (DWORD)-1; + info.dwFlags = 0; +#pragma warning(push) +#if _MSC_VER < 1300 && !defined(_WIN64) +#define ULONG_PTR ULONG +#else +#pragma warning(disable: 6320 6322) +#endif + __try { + RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info); + } + __except (EXCEPTION_EXECUTE_HANDLER) { + } +#pragma warning(pop) +} + +#elif defined(__APPLE__) + +#include +#include +#include + +extern "C" +{ + void *objc_getClass(const char *p); + void *sel_getUid(const char *p); + void *objc_msgSend(void *, void *, ...); +}; + +static void WDL_STATICFUNC_UNUSED WDL_SetThreadName(const char* threadName) { + void *ct=objc_msgSend( objc_getClass("NSThread"), sel_getUid("currentThread")); + CFStringRef tn=CFStringCreateWithCString(NULL,threadName,kCFStringEncodingUTF8); + objc_msgSend(ct,sel_getUid("setName:"), tn); + CFRelease(tn); +#ifdef MAC_OS_X_VERSION_10_6 + pthread_setname_np(threadName); +#endif +} + +#elif defined(__linux__) + +#include + +static void WDL_STATICFUNC_UNUSED WDL_SetThreadName(const char* threadName) { + char tmp[16]; + int x; + for (x=0;*threadName && x<15; threadName++) if (*threadName != ' ') tmp[x++]=*threadName; + tmp[x]=0; + pthread_setname_np(pthread_self(),tmp); +} + +#else + +#define WDL_SetThreadName(x) do { } while (0) + +#endif + +#endif From c947e566c8258d10e2455aa0b150b9b6badf5e9a Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 30 Jul 2018 09:29:28 -0400 Subject: [PATCH 101/144] WDL_FileRead/WDL_FileWrite: use O_CLOEXEC for opening files (disabled on macOS for now until further testing) -- from e7ae438e --- WDL/fileread.h | 7 ++++++- WDL/filewrite.h | 7 ++++++- WDL/shm_connection.cpp | 2 +- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/WDL/fileread.h b/WDL/fileread.h index dd2c9a6d..eb054067 100644 --- a/WDL/fileread.h +++ b/WDL/fileread.h @@ -254,7 +254,12 @@ class WDL_FileRead__ReadEnt #elif defined(WDL_POSIX_NATIVE_READ) m_filedes_locked=false; m_filedes_rdpos=0; - m_filedes=open(filename,O_RDONLY); + m_filedes=open(filename,O_RDONLY +#ifndef __APPLE__ + // todo: we could enable this on macOS, need to test more + | O_CLOEXEC +#endif + ); if (m_filedes>=0) { if (flock(m_filedes,LOCK_SH|LOCK_NB)>=0) // get shared lock diff --git a/WDL/filewrite.h b/WDL/filewrite.h index 18fb9a85..98c68bb0 100644 --- a/WDL/filewrite.h +++ b/WDL/filewrite.h @@ -212,7 +212,12 @@ class WDL_FileWrite__WriteEnt #elif defined(WDL_POSIX_NATIVE_WRITE) m_bufspace_used=0; m_filedes_locked=false; - m_filedes=open(filename,O_WRONLY|O_CREAT,0644); + m_filedes=open(filename,O_WRONLY|O_CREAT +#ifndef __APPLE__ + // todo: we could enable this on macOS, need to test more + | O_CLOEXEC +#endif + ,0644); if (m_filedes>=0) { diff --git a/WDL/shm_connection.cpp b/WDL/shm_connection.cpp index 78fce7af..9b7c778a 100644 --- a/WDL/shm_connection.cpp +++ b/WDL/shm_connection.cpp @@ -305,7 +305,7 @@ WDL_SHM_Connection::WDL_SHM_Connection(bool whichChan, // first created must be { m_lockfn.Set(m_tempfn.Get()); m_lockfn.Append(".lock"); - m_lockhandle = open(m_lockfn.Get(),O_RDWR|O_CREAT,0666); + m_lockhandle = open(m_lockfn.Get(),O_RDWR|O_CREAT|O_CLOEXEC,0666); if (m_lockhandle < 0) return; // error getting lockfile, fail if (flock(m_lockhandle,LOCK_NB|LOCK_EX) < 0) { From ff004565a99dcf57724848eac55b93209283461d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 30 Jul 2018 10:00:51 -0400 Subject: [PATCH 102/144] shm_connection: only use O_CLOEXEC if available -- from 8e333f2d --- WDL/shm_connection.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WDL/shm_connection.cpp b/WDL/shm_connection.cpp index 9b7c778a..662b17ee 100644 --- a/WDL/shm_connection.cpp +++ b/WDL/shm_connection.cpp @@ -305,7 +305,11 @@ WDL_SHM_Connection::WDL_SHM_Connection(bool whichChan, // first created must be { m_lockfn.Set(m_tempfn.Get()); m_lockfn.Append(".lock"); - m_lockhandle = open(m_lockfn.Get(),O_RDWR|O_CREAT|O_CLOEXEC,0666); + m_lockhandle = open(m_lockfn.Get(),O_RDWR|O_CREAT +#ifdef O_CLOEXEC + |O_CLOEXEC +#endif + ,0666); if (m_lockhandle < 0) return; // error getting lockfile, fail if (flock(m_lockhandle,LOCK_NB|LOCK_EX) < 0) { From e87f5bdee7327b63398366fde6ec0a3f08bf600d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 30 Jul 2018 10:03:21 -0400 Subject: [PATCH 103/144] fileread/filewrite: tweak use of O_CLOEXEC -- from 345b3880 --- WDL/fileread.h | 6 ++++-- WDL/filewrite.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/WDL/fileread.h b/WDL/fileread.h index eb054067..f39c23e3 100644 --- a/WDL/fileread.h +++ b/WDL/fileread.h @@ -255,8 +255,10 @@ class WDL_FileRead__ReadEnt m_filedes_locked=false; m_filedes_rdpos=0; m_filedes=open(filename,O_RDONLY -#ifndef __APPLE__ - // todo: we could enable this on macOS, need to test more + // todo: use fcntl() for platforms when O_CLOEXEC is not available (if we ever need to support them) + // (currently the only platform that meets this criteria is macOS w/ old SDK, but we don't use execve() + // there +#ifdef O_CLOEXEC | O_CLOEXEC #endif ); diff --git a/WDL/filewrite.h b/WDL/filewrite.h index 98c68bb0..7517c7ba 100644 --- a/WDL/filewrite.h +++ b/WDL/filewrite.h @@ -213,8 +213,10 @@ class WDL_FileWrite__WriteEnt m_bufspace_used=0; m_filedes_locked=false; m_filedes=open(filename,O_WRONLY|O_CREAT -#ifndef __APPLE__ - // todo: we could enable this on macOS, need to test more + // todo: use fcntl() for platforms when O_CLOEXEC is not available (if we ever need to support them) + // (currently the only platform that meets this criteria is macOS w/ old SDK, but we don't use execve() + // there +#ifdef O_CLOEXEC | O_CLOEXEC #endif ,0644); From 50b9c47f3561c8cf3372f57b68e10fe59f509492 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 31 Jul 2018 23:46:35 -0400 Subject: [PATCH 104/144] + JSFX: gfx_getchar(65536) returns special window information flags + ReaScript: gfx.getchar(65536) or gfx_getchar(65536) return special window information flags -- from f693f9f5 --- WDL/eel2/eel_lice.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index d4bf8318..8debbc0f 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -1933,6 +1933,16 @@ static EEL_F NSEEL_CGEN_CALL _gfx_getchar(void *opaque, EEL_F *p) ctx->m_has_had_getch=true; if (*p >= 2.0) { + if (*p == 65536.0) + { + int rv = 1; + if (ctx->hwnd_standalone) + { + if (ctx->hwnd_standalone==GetFocus()) rv|=2; + if (IsWindowVisible(ctx->hwnd_standalone)) rv|=4; + } + return rv; + } int x; const int n = sizeof(ctx->hwnd_standalone_kb_state) / sizeof(ctx->hwnd_standalone_kb_state[0]); int *st = ctx->hwnd_standalone_kb_state; @@ -2776,6 +2786,7 @@ static const char *eel_lice_function_reference = "\4" "27 for ESC\n" "\4" "13 for Enter\n" "\4' ' for space\n" + "\4" "65536 for query of special flags, returns: &1 (supported), &2=window has focus, &4=window is visible\n" "\2\0" "gfx_showmenu\t\"str\"\tShows a popup menu at gfx_x,gfx_y. str is a list of fields separated by | characters. " From ff1797ad5019e7524c0a03a7dbdd9b470f714b51 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 1 Aug 2018 09:01:13 -0400 Subject: [PATCH 105/144] swell: support loading libSwell-user.colortheme from custom swell-configuration path -- from (reaper.ini path)/libSwell-user.colortheme -- from b473c43f --- WDL/swell/swell.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 2ea433c8..aef145c1 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -1036,6 +1036,9 @@ void *SWELL_ExtendedAPI(const char *key, void *v) { lstrcatn(buf,"/libSwell.colortheme",sizeof(buf)); swell_load_color_theme(buf); + WDL_remove_fileext(buf); + lstrcatn(buf,"-user.colortheme",sizeof(buf)); + swell_load_color_theme(buf); } } From 1d8af4441ae56774e25b135990c1dca042a3f29d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 4 Aug 2018 10:59:00 -0400 Subject: [PATCH 106/144] eel_lice: gfx_deltablit() can take a usecliprect=0 parameter -- from ee8b79a7 --- WDL/eel2/eel_lice.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index 8debbc0f..3cb1e06b 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -1287,7 +1287,7 @@ void eel_lice_state::gfx_blitext2(int np, EEL_F **parms, int blitmode) np > 12 ? (float)parms[12][0]:1.0f, // dtdy np > 13 ? (float)parms[13][0]:0.0f, // dsdxdy np > 14 ? (float)parms[14][0]:0.0f, // dtdxdy - true, (float)*m_gfx_a,getCurModeForBlit(isFromFB)); + np <= 15 || parms[15][0] > 0.5, (float)*m_gfx_a,getCurModeForBlit(isFromFB)); } else if (fabs(angle)>0.000000001) { @@ -2834,9 +2834,9 @@ static const char *eel_lice_function_reference = "gfx_loadimg\timage,\"filename\"\tLoad image from filename into slot 0.." EEL_LICE_DOC_MAXHANDLE " specified by image. Returns the image index if success, otherwise -1 if failure. The image will be resized to the dimensions of the image file. \0" "gfx_gradrect\tx,y,w,h, r,g,b,a[, drdx, dgdx, dbdx, dadx, drdy, dgdy, dbdy, dady]\tFills a gradient rectangle with the color and alpha specified. drdx-dadx reflect the adjustment (per-pixel) applied for each pixel moved to the right, drdy-dady are the adjustment applied for each pixel moved toward the bottom. Normally drdx=adjustamount/w, drdy=adjustamount/h, etc.\0" "gfx_muladdrect\tx,y,w,h,mul_r,mul_g,mul_b[,mul_a,add_r,add_g,add_b,add_a]\tMultiplies each pixel by mul_* and adds add_*, and updates in-place. Useful for changing brightness/contrast, or other effects.\0" - "gfx_deltablit\tsrcimg,srcx,srcy,srcw,srch,destx,desty,destw,desth,dsdx,dtdx,dsdy,dtdy,dsdxdy,dtdxdy\tBlits from srcimg(srcx,srcy,srcw,srch) " + "gfx_deltablit\tsrcimg,srcs,srct,srcw,srch,destx,desty,destw,desth,dsdx,dtdx,dsdy,dtdy,dsdxdy,dtdxdy[,usecliprect=1]\tBlits from srcimg(srcx,srcy,srcw,srch) " "to destination (destx,desty,destw,desth). Source texture coordinates are s/t, dsdx represents the change in s coordinate for each x pixel" - ", dtdy represents the change in t coordinate for each y pixel, etc. dsdxdy represents the change in dsdx for each line. \0" + ", dtdy represents the change in t coordinate for each y pixel, etc. dsdxdy represents the change in dsdx for each line. If usecliprect is specified and 0, then srcw/srch are ignored.\0" "gfx_transformblit\tsrcimg,destx,desty,destw,desth,div_w,div_h,table\tBlits to destination at (destx,desty), size (destw,desth). " "div_w and div_h should be 2..64, and table should point to a table of 2*div_w*div_h values (this table must not cross a " "65536 item boundary). Each pair in the table represents a S,T coordinate in the source image, and the table is treated as " From 99dd088f8704a2d726f93d4c1dc3d2180a6a0ddb Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 6 Aug 2018 14:15:12 -0400 Subject: [PATCH 107/144] swell: correct some outdated comments -- from 6475acb0 --- WDL/swell/swell-functions.h | 284 ++++++++++++++---------------------- WDL/swell/swell-types.h | 4 +- 2 files changed, 109 insertions(+), 179 deletions(-) diff --git a/WDL/swell/swell-functions.h b/WDL/swell/swell-functions.h index bcf304d3..75fa11fa 100644 --- a/WDL/swell/swell-functions.h +++ b/WDL/swell/swell-functions.h @@ -52,6 +52,9 @@ ** lstrcpyn: this is provided because strncpy is braindead (filling with zeroes, and not ** NULL terminating if the destination buffer is too short? ASKING for trouble..) ** lstrpcyn always null terminates the string and doesnt fill anything extra. +** +** note: wdlcstring.h defines lstrcpyn_safe(), which is preferred on win32 because of +** exception handling behavior. */ SWELL_API_DEFINE(char *, lstrcpyn, (char *dest, const char *src, int l)) @@ -70,7 +73,7 @@ SWELL_API_DEFINE(int, MulDiv, (int, int, int)) SWELL_API_DEFINE(void, Sleep,(int ms)) /* -** GetTickCount() and timeGetTime() give you ms level timings via gettimeofday(). +** GetTickCount() and timeGetTime() give you ms level timings via gettimeofday() or mach_getabsolutetime() or clock_gettime() ** ** NOTE: This doesn't map to time since system start (like in win32), so a wrap around ** is slightly more likely (i.e. even if you booted your system an hour ago it could happen). @@ -97,6 +100,8 @@ SWELL_API_DEFINE(BOOL, GetFileTime,(int filedes, FILETIME *lpCreationTime, FILET ** the filename used MUST be the full filename, unlike on Windows where files without paths go to ** C:/Windows, here they will be opened in the current directory. ** +** You can pass an empty string for filename to use ~/.libSwell.ini (that can be overridden by the app) +** ** It's probably not a good idea to push your luck with simultaneous writes from multiple ** modules in different threads/processes, but in theory it should work. */ @@ -125,27 +130,24 @@ SWELL_API_DEFINE(void, SWELL_CFStringToCString, (const void *str, char *buf, int #endif -/* -** PtInRect() should hopefully function just like it's win32 equivelent. -** there is #define funkiness because some Mac system headers define PtInRect as well. -*/ #ifdef PtInRect #undef PtInRect +// #define funkiness because some Mac system headers define PtInRect as well. #endif #define PtInRect(r,p) SWELL_PtInRect(r,p) SWELL_API_DEFINE(BOOL, SWELL_PtInRect,(const RECT *r, POINT p)) /* ** ShellExecute(): -** NOTE: currently action is ignored, and it only works on content1 being an app, an URL beginning with http://, -** "notepad.exe" (content2=file to open), or "explorer.exe" (content2=folder to open, or content2=/select,"file_to_reveal_if_10.6+") -** TODO: finish implementation +** notes: +** action is ignored +** content1 can be a http:// or https:// URL +** content1 can be notepad/notepad.exe (maps to xdg-open or TextEdit.app) w/ content2 as a document +** content1 can be explorer.exe (optionally with /select) (maps to open finder or xdg-open) +** otherwise content1 can be an app w/ parameters in content2 */ SWELL_API_DEFINE(BOOL, ShellExecute,(HWND hwndDlg, const char *action, const char *content1, const char *content2, const char *content3, int blah)) -/* -** MessageBox(). -*/ SWELL_API_DEFINE(int, MessageBox,(HWND hwndParent, const char *text, const char *caption, int type)) @@ -173,31 +175,18 @@ SWELL_API_DEFINE(void,BrowseFile_SetTemplate,(const char *dlgid, DLGPROC dlgProc // Note that window functions are generally NOT threadsafe. -// all of these treat HWND as NSView and/or NSWindow (usually smartish about it) - +// on macOS: all of these treat HWND as NSView and/or NSWindow (usually smartish about it) /* -** GetDlgItem(hwnd,0) returns hwnd if hwnd is a NSView, or the contentview if hwnd is a NSWindow. -** Note that this GetDlgItem will actually search a view hierarchy for the tagged view, -** unlike Win32 where it will only look at immediate children. + * GetDlgItem() notes: +** macOS: GetDlgItem(hwnd,0) returns hwnd if hwnd is a NSView, or the contentview if hwnd is a NSWindow. +** macOS: note that this GetDlgItem will actually search a view hierarchy for the tagged view (win32 or -generic will only search immediate children) */ SWELL_API_DEFINE(HWND, GetDlgItem,(HWND, int)) -/* -** ShowWindow() works for hwnds that represent NSView and/or NSWindow. -** SW_SHOW, SW_SHOWNA, and SW_HIDE are defined, and some of the other common uses -** alias to these. -*/ -SWELL_API_DEFINE(void, ShowWindow,(HWND, int)) +SWELL_API_DEFINE(void, ShowWindow,(HWND, int)) -/* -** DestroyWindow() works for both a NSWindow or NSView. -** Note that if the window is a fake window with a procedure -** (created via CreateDialog or DialogBox below) then WM_DESTROY -** will be called immediately, though the window/view may be freed -** sometime later via the autorelease pool. -*/ SWELL_API_DEFINE(void, DestroyWindow,(HWND hwnd)) SWELL_API_DEFINE(BOOL, SWELL_GetGestureInfo, (LPARAM lParam, GESTUREINFO* gi)) @@ -206,8 +195,9 @@ SWELL_API_DEFINE(void, SWELL_HideApp,()) /* ** These should all work like their Win32 versions, though if idx=0 it gets/sets the -** value for the window. Note that SetDlgItemText() for an edit control does NOT send -** a WM_COMMAND notification like on win32, so you will have to do this yourself. +** value for the window. +** +** macOS: SetDlgItemText() for an edit control does NOT send a WM_COMMAND notification (win32 and -generic do) */ SWELL_API_DEFINE(BOOL, SetDlgItemText,(HWND, int idx, const char *text)) SWELL_API_DEFINE(BOOL, SetDlgItemInt,(HWND, int idx, int val, int issigned)) @@ -223,9 +213,9 @@ SWELL_API_DEFINE(BOOL, GetDlgItemText,(HWND, int idx, char *text, int textlen)) SWELL_API_DEFINE(void, CheckDlgButton,(HWND hwnd, int idx, int check)) SWELL_API_DEFINE(int, IsDlgButtonChecked,(HWND hwnd, int idx)) SWELL_API_DEFINE(void, EnableWindow,(HWND hwnd, int enable)) -SWELL_API_DEFINE(void, SetFocus,(HWND hwnd)) // these take NSWindow/NSView, and return NSView * +SWELL_API_DEFINE(void, SetFocus,(HWND hwnd)) SWELL_API_DEFINE(HWND, GetFocus,()) -SWELL_API_DEFINE(void, SetForegroundWindow,(HWND hwnd)) // these take NSWindow/NSView, and return NSView * +SWELL_API_DEFINE(void, SetForegroundWindow,(HWND hwnd)) SWELL_API_DEFINE(HWND, GetForegroundWindow,()) #ifndef GetActiveWindow #define GetActiveWindow() GetForegroundWindow() @@ -235,14 +225,7 @@ SWELL_API_DEFINE(HWND, GetForegroundWindow,()) #endif /* -** GetCapture/SetCapture/ReleaseCapture are completely faked, with just an internal state. -** Mouse click+drag automatically captures the focus sending mouseDrag events in OSX, so -** these are as a porting aid. -** -** Updated: they actually send WM_CAPTURECHANGED messages now, if the window supports -** onSwellMessage:p1:p2: and swellCapChangeNotify (and swellCapChangeNotify returns YES). -** -** Note that any HWND that returns YES to swellCapChangeNotify should do the following on +** macOS: note that any HWND that returns YES to swellCapChangeNotify should do the following on ** destroy or dealloc: if (GetCapture()==(HWND)self) ReleaseCapture(); Failure to do so ** can cause a dealloc'd window to get messages sent to it. */ @@ -252,33 +235,19 @@ SWELL_API_DEFINE(void, ReleaseCapture,()) /* ** IsChild() -** Notes: hwndChild must be a NSView (if not then false is returned) -** hwndParent can be a NSWindow or NSView. -** NSWindow level ownership/children are not detected. +** macOS: hwndChild must be a NSView, hwndParent can be a NSWindow or NSView. NSWindow level ownership/children are not detected. */ SWELL_API_DEFINE(int, IsChild,(HWND hwndParent, HWND hwndChild)) -/* -** GetParent() -** Notes: if hwnd is a NSView, then gets the parent view (or NSWindow -** if the parent view is the window's contentview). If hwnd is a NSWindow, -** then GetParent returns the owner window, if any. Note that the owner -** window system is not part of OSX, but rather part of SWELL. -*/ SWELL_API_DEFINE(HWND, GetParent,(HWND hwnd)) /* ** SetParent() -** Notes: hwnd must be a NSView, newPar can be either NSView or NSWindow. +** macOS: hwnd must be a NSView, newPar can be either NSView or NSWindow. */ SWELL_API_DEFINE(HWND, SetParent,(HWND hwnd, HWND newPar)) -/* -** GetWindow() -** Most of the standard GW_CHILD etc work. Does not do anything to prevent you from -** getting into infinite loops if you go changing the order on the fly etc. -*/ SWELL_API_DEFINE(HWND, GetWindow,(HWND hwnd, int what)) SWELL_API_DEFINE(BOOL, EnumWindows, (BOOL (*proc)(HWND, LPARAM), LPARAM lp)) @@ -287,7 +256,7 @@ SWELL_API_DEFINE(HWND,FindWindowEx,(HWND par, HWND lastw, const char *classname, /* -** Notes: common win32 code like this: +** macOS note: common win32 code like this: ** RECT r; ** GetWindowRect(hwnd,&r); ** ScreenToClient(otherhwnd,(LPPOINT)&r); @@ -296,7 +265,7 @@ SWELL_API_DEFINE(HWND,FindWindowEx,(HWND par, HWND lastw, const char *classname, ** than r.top, due to flipped coordinates. SetWindowPos and other functions ** handle negative heights gracefully, and you should too. ** -** Note: GetWindowContentViewRect gets the rectangle of the content view (pre-NCCALCSIZE etc) +** GetWindowContentViewRect gets the rectangle of the content view (pre-NCCALCSIZE etc) */ SWELL_API_DEFINE(void, ClientToScreen,(HWND hwnd, POINT *p)) SWELL_API_DEFINE(void, ScreenToClient,(HWND hwnd, POINT *p)) @@ -309,49 +278,38 @@ SWELL_API_DEFINE(BOOL, WinSetRect, (LPRECT lprc, int xLeft, int yTop, int xRight SWELL_API_DEFINE(void,WinUnionRect,(RECT *out, const RECT *in1, const RECT *in2)) SWELL_API_DEFINE(int,WinIntersectRect,(RECT *out, const RECT *in1, const RECT *in2)) - -/* -** SetWindowPos(): -** Notes: Z ordering stuff is ignored, as are most flags. -** SWP_NOMOVE and SWP_NOSIZE are the only flags used. -*/ SWELL_API_DEFINE(void, SetWindowPos,(HWND hwnd, HWND unused, int x, int y, int cx, int cy, int flags)) SWELL_API_DEFINE(int, SWELL_SetWindowLevel, (HWND hwnd, int newlevel)) -/* -** InvalidateRect() -** Notes: eraseBk is ignored, probably not threadsafe! hwnd can be NSWindow or NSView -*/ SWELL_API_DEFINE(BOOL,InvalidateRect,(HWND hwnd, const RECT *r, int eraseBk)) -/* -** UpdateWindow() -** Notes: not currently implemented but provided here in case someday it is necessary -*/ SWELL_API_DEFINE(void,UpdateWindow,(HWND hwnd)) /* ** GetWindowLong()/SetWindowLong() ** -** GWL_ID is supported for all objects that support the 'tag'/'setTag' methods, -** which would be controls and SWELL created windows/dialogs/controls. +** macOS: +** GWL_ID is supported for all objects that support the 'tag'/'setTag' methods, +** which would be controls and SWELL created windows/dialogs/controls. ** -** GWL_USERDATA is supported by SWELL created windows/dialogs/controls, using -** (int)getSwellUserData and setSwellUserData:(int). +** GWL_USERDATA is supported by SWELL created windows/dialogs/controls, using +** (int)getSwellUserData and setSwellUserData:(int). ** -** GWL_WNDPROC is supported by SWELL created windows/dialogs/controls, using -** (int)getSwellWindowProc and setSwellWindowProc:(int). +** GWL_WNDPROC is supported by SWELL created windows/dialogs/controls, using +** (int)getSwellWindowProc and setSwellWindowProc:(int). +** +** DWL_DLGPROC is supported by SWELL-created dialogs now (it might work in windows/controls but isnt recommended) ** -** DWL_DLGPROC is supported by SWELL created dialogs now (it might work in windows/controls but isnt recommended) +** GWL_STYLE is only supported for NSButton. Currently the only flags supported are +** BS_AUTO3STATE (BS_AUTOCHECKBOX is returned but also ignored). ** -** GWL_STYLE is only supported for NSButton. Currently the only flags supported are -** BS_AUTO3STATE (BS_AUTOCHECKBOX is returned but also ignored). +** indices of >= 0 and < 128 (32 integers) are supported for SWELL created +** windows/dialogs/controls, via (int)getSwellExtraData:(int)idx and +** setSwellExtraData:(int)idx value:(int)val . ** -** indices of >= 0 and < 128 (32 integers) are supported for SWELL created -** windows/dialogs/controls, via (int)getSwellExtraData:(int)idx and -** setSwellExtraData:(int)idx value:(int)val . +** generic: indices of >= 0 && < 64*sizeof(INT_PTR) are supported */ SWELL_API_DEFINE(LONG_PTR, GetWindowLong,(HWND hwnd, int idx)) SWELL_API_DEFINE(LONG_PTR, SetWindowLong,(HWND hwnd, int idx, LONG_PTR val)) @@ -361,7 +319,7 @@ SWELL_API_DEFINE(BOOL, ScrollWindow, (HWND hwnd, int xamt, int yamt, const RECT /* ** GetProp() SetProp() RemoveProp() EnumPropsEx() -** These should work like in win32. Free your props otherwise they will leak. +** Free your props otherwise they will leak. ** Restriction on what you can do in the PROPENUMPROCEX is similar to win32 ** (you can remove only the called prop, and can't add props within it). ** if the prop name is < (void *)65536 then it is treated as a short identifier. @@ -374,24 +332,29 @@ SWELL_API_DEFINE(HANDLE, RemoveProp, (HWND, const char *)) /* ** IsWindowVisible() -** if hwnd is a NSView, returns !isHiddenOrHasHiddenAncestor -** if hwnd is a NSWindow returns isVisible -** otherwise returns TRUE if non-null hwnd +** macOS: +** if hwnd is a NSView, returns !isHiddenOrHasHiddenAncestor +** if hwnd is a NSWindow returns isVisible +** otherwise returns TRUE if non-null hwnd */ SWELL_API_DEFINE(bool, IsWindowVisible,(HWND hwnd)) -SWELL_API_DEFINE(bool, IsWindow, (HWND hwnd)) // very costly (compared to win32) -- enumerates all windows, searches for hwnd +// IsWindow() +// probably best avoided. +// macOS: very costly (compared to win32) -- enumerates all windows, searches for hwnd +// generic: may not be implemented +SWELL_API_DEFINE(bool, IsWindow, (HWND hwnd)) /* ** SetTimer/KillTimer(): ** Notes: -** The timer API may be threadsafe though it is highly untested. -** Note also that the mechanism for sending timers is SWELL_Timer:(id). -** The fourth parameter to SetTimer() is not supported and will be ignored, so you must -** receive your timers via a WM_TIMER (or SWELL_Timer:(id)) +** The timer API may be threadsafe though it is highly untested. It is safest to only set +** timers from the main thread. ** -** You can kill all timers for a window using KillTimer(hwnd,-1); +** Kill all timers for a window using KillTimer(hwnd,-1); +** +** macOS: Note also that the mechanism for sending timers is SWELL_Timer:(id). ** You MUST kill all timers for a window before destroying it. Note that SWELL created ** windows/dialogs/controls automatically do this, but if you use SetTimer() on a NSView * ** or NSWindow * directly, then you should kill all timers in -dealloc. @@ -401,17 +364,14 @@ SWELL_API_DEFINE(BOOL, KillTimer,(HWND hwnd, UINT_PTR timerid)) #ifdef SWELL_TARGET_OSX /* -** These provide the interfaces for directly updating a combo box control. This is no longer -** required as SendMessage can now be used with CB_* etc. -** Combo boxes may be implemented using a NSComboBox or NSPopUpButton depending on the style. -** -** Notes: CB_SetItemData/CB_GetItemData only work for the non-user-editable version (using NSPopUpbutotn). +** SendMessage can/should now be used with CB_* etc. +** macOS: Combo boxes may be implemented using a NSComboBox or NSPopUpButton depending on the style. */ SWELL_API_DEFINE(int, SWELL_CB_AddString,(HWND hwnd, int idx, const char *str)) SWELL_API_DEFINE(void, SWELL_CB_SetCurSel,(HWND hwnd, int idx, int sel)) SWELL_API_DEFINE(int, SWELL_CB_GetCurSel,(HWND hwnd, int idx)) SWELL_API_DEFINE(int, SWELL_CB_GetNumItems,(HWND hwnd, int idx)) -SWELL_API_DEFINE(void, SWELL_CB_SetItemData,(HWND hwnd, int idx, int item, LONG_PTR data)) // these two only work for the combo list version for now +SWELL_API_DEFINE(void, SWELL_CB_SetItemData,(HWND hwnd, int idx, int item, LONG_PTR data)) SWELL_API_DEFINE(LONG_PTR, SWELL_CB_GetItemData,(HWND hwnd, int idx, int item)) SWELL_API_DEFINE(void, SWELL_CB_Empty,(HWND hwnd, int idx)) SWELL_API_DEFINE(int, SWELL_CB_InsertString,(HWND hwnd, int idx, int pos, const char *str)) @@ -422,8 +382,7 @@ SWELL_API_DEFINE(int, SWELL_CB_FindString,(HWND hwnd, int idx, int startAfter, c /* ** Trackbar API -** These provide the interfaces for directly updating a trackbar (implemented using NSSlider). -** Note that you can now use SendMessage with TBM_* instead. +** You can/should now use SendMessage with TBM_* instead. */ SWELL_API_DEFINE(void, SWELL_TB_SetPos,(HWND hwnd, int idx, int pos)) SWELL_API_DEFINE(void, SWELL_TB_SetRange,(HWND hwnd, int idx, int low, int hi)) @@ -434,8 +393,7 @@ SWELL_API_DEFINE(void, SWELL_TB_SetTic,(HWND hwnd, int idx, int pos)) #endif /* -** ListView API. In owner data mode only LVN_GETDISPINFO is used (not ODFINDITEM etc). -** LVN_BEGINDRAG also should work as on windows. Imagelists state icons work as well. +** ListViews -- in owner data mode only LVN_GETDISPINFO is required (LVN_ODFINDITEM is never sent) */ SWELL_API_DEFINE(void, ListView_SetExtendedListViewStyleEx,(HWND h, int mask, int style)) SWELL_API_DEFINE(void, ListView_InsertColumn,(HWND h, int pos, const LVCOLUMN *lvc)) @@ -528,7 +486,7 @@ SWELL_API_DEFINE(void,ListView_SetGridColor,(HWND hwnd, int color)) SWELL_API_DEFINE(void,ListView_SetSelColors,(HWND hwnd, int *colors, int ncolors)) /* -** These are deprecated functions for launching a modal window but still running +** These are deprecated macOS-only functions for launching a modal window but still running ** your own code. In general use DialogBox with a timer if needed instead. */ SWELL_API_DEFINE(void *, SWELL_ModalWindowStart,(HWND hwnd)) @@ -536,10 +494,9 @@ SWELL_API_DEFINE(bool, SWELL_ModalWindowRun,(void *ctx, int *ret)) // returns fa SWELL_API_DEFINE(void, SWELL_ModalWindowEnd,(void *ctx)) SWELL_API_DEFINE(void, SWELL_CloseWindow,(HWND hwnd)) - /* ** Menu functions -** HMENU is a NSMenu *. +** macOS: HMENU is a NSMenu *. */ SWELL_API_DEFINE(HMENU, CreatePopupMenu,()) SWELL_API_DEFINE(HMENU, CreatePopupMenuEx,(const char *title)) @@ -570,9 +527,9 @@ SWELL_API_DEFINE(void, DrawMenuBar,(HWND)) ** LoadMenu() ** Loads a menu created with SWELL_DEFINE_MENU_RESOURCE_BEGIN(), see swell-menugen.h ** Notes: the hinst parameter is ignored, the menu must have been defined in the same -** APP or DYLIB as the LoadMenu call. If you wish to load a menu from another module, -** you should somehow get its SWELL_curmodule_menuresource_head and pass it to SWELL_LoadMenu -** directly. +** module (executable or shared library) as the LoadMenu call. If you wish to load a +** menu from another module, get its SWELL_curmodule_menuresource_head and pass it to +** SWELL_LoadMenu directly. */ #ifndef LoadMenu #define LoadMenu(hinst,resid) SWELL_LoadMenu(SWELL_curmodule_menuresource_head,(resid)) @@ -581,15 +538,13 @@ SWELL_API_DEFINE(HMENU, SWELL_LoadMenu,(struct SWELL_MenuResourceIndex *head, co /* ** TrackPopupMenu -** Notes: the rectangle and many flags are ignored, but TPM_NONOTIFY is used. -** It always returns the command selected, even if TPM_RETURNCMD is not specified. +** Notes: the rectangle is ignored, and resvd should always be 0. */ SWELL_API_DEFINE(int, TrackPopupMenu,(HMENU hMenu, int flags, int xpos, int ypos, int resvd, HWND hwnd, const RECT *r)) /* -** SWELL_SetMenuDestination: set the action destination for all items in a menu -** Notes: -** TrackPopupMenu and SetMenu use this internally, but it may be useful. +** SWELL_SetMenuDestination: set the action destination for all items and subitems in a menu +** macOS only, TrackPopupMenu and SetMenu use this internally, but it may be useful. */ SWELL_API_DEFINE(void, SWELL_SetMenuDestination,(HMENU menu, HWND hwnd)) @@ -601,20 +556,20 @@ SWELL_API_DEFINE(HMENU, SWELL_DuplicateMenu,(HMENU menu)) /* ** SetMenu()/GetMenu() -** Notes: These work on SWELL created NSWindows, or objective C objects that respond to -** swellSetMenu:(HMENU) and swellGetMenu. -** Setting these values doesnt mean anything, except that the SWELL windows will automatically -** set the application menu via NSApp setMainMenu: when activated. -** +** macOS: These work on SWELL created NSWindows, or objective C objects that respond to +** swellSetMenu:(HMENU) and swellGetMenu. SWELL windows will automatically set the +** application menu via NSApp setMainMenu: when activated. */ SWELL_API_DEFINE(BOOL, SetMenu,(HWND hwnd, HMENU menu)) SWELL_API_DEFINE(HMENU, GetMenu,(HWND hwnd)) /* ** SWELL_SetDefaultWindowMenu()/SWELL_GetDefaultWindowMenu() -** these set an internal flag for the default window menu, which will be set +** macOS: these set an internal flag for the default window menu, which will be set ** when switching to a window that has no menu set. Set this to your application's ** main menu. +** +** generic: these set the internal state, which is currently unused */ SWELL_API_DEFINE(HMENU, SWELL_GetDefaultWindowMenu,()) SWELL_API_DEFINE(void, SWELL_SetDefaultWindowMenu,(HMENU)) @@ -631,12 +586,12 @@ SWELL_API_DEFINE(void, SWELL_SetCurrentMenu,(HMENU)) ** ** Notes: ** hInstance parameters are ignored. If you wish to load a dialog resource from another -** module (DYLIB), you should get its SWELL_curmodule_dialogresource_head via your own -** mechanism and pass it as the first parameter of SWELL_DialogBox or whichever API. +** module (shared library/executable), you should get its SWELL_curmodule_dialogresource_head +** via your own mechanism and pass it as the first parameter of SWELL_DialogBox or whichever API. ** ** If you are using CreateDialog() and creating a child window, you can use a resource ID of ** 0, which creates an opaque child window. Instead of passing a DLGPROC, you should pass a -** routine that retuns LRESULT (and cast it to DLGPROC). +** (WNDPROC) routine that retuns LRESULT (and cast it to DLGPROC). ** */ @@ -654,23 +609,13 @@ SWELL_API_DEFINE(HWND, SWELL_CreateDialog,(struct SWELL_DialogResourceIndex *res ** SWELL_RegisterCustomControlCreator(), SWELL_UnregisterCustomControlCreator() ** Notes: ** Pass these a callback function that can create custom controls based on classname. -** Todo: document. */ SWELL_API_DEFINE(void, SWELL_RegisterCustomControlCreator,(SWELL_ControlCreatorProc proc)) SWELL_API_DEFINE(void, SWELL_UnregisterCustomControlCreator,(SWELL_ControlCreatorProc proc)) -/* -** DefWindowProc(). -** Notes: Doesnt do much but call it anyway from any child windows created with CreateDialog -** and a 0 resource-id window proc. -*/ SWELL_API_DEFINE(LRESULT, DefWindowProc,(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)) -/* -** EndDialog(): -** Notes: _ONLY_ use on a dialog created with DialogBox(). Will do nothing on other dialogs. -*/ SWELL_API_DEFINE(void, EndDialog,(HWND, int)) @@ -683,20 +628,17 @@ SWELL_API_DEFINE(int,SWELL_GetDefaultButtonID,(HWND hwndDlg, bool onlyIfEnabled) ** LIMITATION - SendMessage should only be used from the same thread that the window/view ** was created in. Cross-thread use SHOULD BE AVOIDED. It may work, but it may blow up. ** PostMessage (below) can be used in certain instances for asynchronous notifications. -** -** If the hwnd supports onSwellMessage:p1:p2: then the message is sent via this. -** Alternatively, buttons created via the dialog interface support BM_GETIMAGE/BM_SETIMAGE -** NSPopUpButton and NSComboBox controls support CB_* -** NSSlider controls support TBM_* -** If the receiver is a view and none of these work, the message goes to the window's onSwellMessage, if any -** If the receiver is a window and none of these work, the message goes to the window's contentview's onSwellMessage, if any -** */ SWELL_API_DEFINE(LRESULT, SendMessage,(HWND, UINT, WPARAM, LPARAM)) + #ifndef SendDlgItemMessage #define SendDlgItemMessage(hwnd,idx,msg,wparam,lparam) SendMessage(GetDlgItem(hwnd,idx),msg,wparam,lparam) #endif +/* +** SWELL_BroadcastMessage() +** sends a message to all top-level windows +*/ SWELL_API_DEFINE(void,SWELL_BroadcastMessage,(UINT, WPARAM, LPARAM)) /* @@ -748,22 +690,24 @@ SWELL_API_DEFINE(int,SWELL_KeyToASCII,(int wParam, int lParam, int *newflags)) /* ** GetAsyncKeyState() -** Notes: only supports MK_LBUTTON, MK_RBUTTON, MK_MBUTTON, VK_SHIFT, VK_MENU, and VK_CONTROL (apple key) for now. +** macOS: only supports VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_SHIFT, VK_MENU, VK_CONTROL (apple/command key), VK_LWIN (control key) +** GDK: only supports VK_LBUTTON, VK_RBUTTON, VK_MBUTTON, VK_SHIFT, VK_MENU, VK_CONTROL, VK_LWIN */ SWELL_API_DEFINE(WORD, GetAsyncKeyState,(int key)) /* ** GetCursorPos(), GetMessagePos() -** Notes: GetMessagePos() currently returns the same coordinates as GetCursorPos(), -** this needs to be fixed. +** GetMessagePos() currently returns the same coordinates as GetCursorPos() */ SWELL_API_DEFINE(void, GetCursorPos,(POINT *pt)) SWELL_API_DEFINE(DWORD, GetMessagePos,()) /* ** LoadCursor(). -** Notes: hinstance parameter ignored, currently only supports loading some of the predefined values. -** (IDC_SIZEALL etc). If it succeeds value is a NSCursor * +** Notes: hinstance parameter ignored, supports loading some of the predefined values (e.g. IDC_SIZEALL) +** and cursors registered into the main module +** macOS: HCURSOR = NSCursor * +** see also: SWELL_LoadCursorFromFile */ SWELL_API_DEFINE(HCURSOR, SWELL_LoadCursor,(const char *idx)) #ifndef LoadCursor @@ -772,7 +716,7 @@ SWELL_API_DEFINE(HCURSOR, SWELL_LoadCursor,(const char *idx)) /* ** SetCursor() -** Sets a cursor as active (can be HCURSOR or NSCursor * cast as such). +** macOS: can cast a NSCursor* to HCURSOR if desired */ #ifdef SetCursor #undef SetCursor @@ -803,6 +747,8 @@ SWELL_API_DEFINE(void, SWELL_SetCursor,(HCURSOR curs)) /* +** SWELL_EnableRightClickEmulate() +** macOS only ** Globally enable or disable emulating mouse right-click using control+left-click */ SWELL_API_DEFINE(void, SWELL_EnableRightClickEmulate, (BOOL enable)) @@ -827,9 +773,9 @@ SWELL_API_DEFINE(BOOL, SWELL_SetCursorPos, (int X, int Y)) SWELL_API_DEFINE(void, SWELL_GetViewPort,(RECT *r, const RECT *sourcerect, bool wantWork)) /* -** Clipboard API emulation -** Notes: setting multiple types may not work right -** +** Clipboard API +** macOS: setting multiple types may not be supported +** GDK: only CF_TEXT is shared with system, other types are stored internally */ SWELL_API_DEFINE(bool, OpenClipboard,(HWND hwndDlg)) SWELL_API_DEFINE(void, CloseClipboard,()) @@ -841,15 +787,10 @@ SWELL_API_DEFINE(UINT, RegisterClipboardFormat,(const char *desc)) SWELL_API_DEFINE(UINT, EnumClipboardFormats,(UINT lastfmt)) #ifndef CF_TEXT + // do not use 'static int globalvalue = CF_TEXT' as this will cause problems (RegisterClipboardFormat() being called too soon!). #define CF_TEXT (RegisterClipboardFormat("SWELL__CF_TEXT")) #endif -/* -** GlobalAlloc*() -** These are only currently used by the clipboard system, -** but should work normally. -*/ - SWELL_API_DEFINE(HANDLE, GlobalAlloc,(int flags, int sz)) SWELL_API_DEFINE(void *, GlobalLock,(HANDLE h)) SWELL_API_DEFINE(int, GlobalSize,(HANDLE h)) @@ -869,7 +810,7 @@ SWELL_API_DEFINE(HANDLE,CreateEventAsSocket,(void *SA, BOOL manualReset, BOOL in SWELL_API_DEFINE(DWORD,GetCurrentThreadId,()) SWELL_API_DEFINE(DWORD,WaitForSingleObject,(HANDLE hand, DWORD msTO)) -SWELL_API_DEFINE(DWORD,WaitForAnySocketObject,(int numObjs, HANDLE *objs, DWORD msTO)) // waits for any number of socket objects +SWELL_API_DEFINE(DWORD,WaitForAnySocketObject,(int numObjs, HANDLE *objs, DWORD msTO)) SWELL_API_DEFINE(BOOL,CloseHandle,(HANDLE hand)) SWELL_API_DEFINE(BOOL,SetThreadPriority,(HANDLE evt, int prio)) SWELL_API_DEFINE(BOOL,SetEvent,(HANDLE evt)) @@ -895,19 +836,10 @@ SWELL_API_DEFINE(BOOL,FreeLibrary,(HINSTANCE hInst)) SWELL_API_DEFINE(void*,SWELL_GetBundle,(HINSTANCE hInst)) -/* -** GDI functions. -** Everything should be all hunky dory, your windows may get WM_PAINT, call -** GetDC()/ReleaseDC(), etc. -** -** Or, there are these helper functions: -*/ - - /* ** SWELL_CreateMemContext() ** Creates a memory context (that you can get the bits for, below) -** hdc is currently ignored. +** hdc is ignored */ SWELL_API_DEFINE(HDC, SWELL_CreateMemContext,(HDC hdc, int w, int h)) @@ -919,7 +851,8 @@ SWELL_API_DEFINE(void, SWELL_DeleteGfxContext,(HDC)) /* ** SWELL_GetCtxGC() -** Returns the CGContextRef of a HDC +** macOS: Returns the CGContextRef of a HDC +** GDK: returns NULL */ SWELL_API_DEFINE(void *, SWELL_GetCtxGC,(HDC ctx)) @@ -934,6 +867,7 @@ SWELL_API_DEFINE(void *, SWELL_GetCtxFrameBuffer,(HDC ctx)) /* ** Some utility functions for pushing, setting, and popping the clip region. +** macOS-only */ SWELL_API_DEFINE(void, SWELL_PushClipRegion,(HDC ctx)) SWELL_API_DEFINE(void, SWELL_SetClipRegion,(HDC ctx, const RECT *r)) @@ -941,11 +875,6 @@ SWELL_API_DEFINE(void, SWELL_PopClipRegion,(HDC ctx)) -/* -** GDI emulation functions -** todo: document -*/ - SWELL_API_DEFINE(HFONT, CreateFontIndirect,(LOGFONT *)) SWELL_API_DEFINE(HFONT, CreateFont,(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, @@ -1060,8 +989,9 @@ SWELL_API_DEFINE(void, SWELL_FinishDragDrop, ()) // cancels any outstanding Ini -// r=NULL to "free" handle -// otherwise r is in hwndPar coordinates +// focus rects aren't implemented as XOR as on win32, might be a straight blit or a separate window +// rct=NULL to "free" handle +// otherwise rct is in hwndPar coordinates SWELL_API_DEFINE(void,SWELL_DrawFocusRect,(HWND hwndPar, RECT *rct, void **handle)) diff --git a/WDL/swell/swell-types.h b/WDL/swell/swell-types.h index 04d59894..55ad538c 100644 --- a/WDL/swell/swell-types.h +++ b/WDL/swell/swell-types.h @@ -1186,11 +1186,11 @@ __attribute__ ((visibility ("default"))) BOOL WINAPI DllMain(HINSTANCE hInstDLL, #define VK_NUMLOCK 0x90 #define VK_SCROLL 0x91 -#define MK_LBUTTON 0x01 +// these should probably not be used (wParam is not set in WM_LBUTTONDOWN/WM_MOUSEMOVE etc) +#define MK_LBUTTON 0x01 #define MK_RBUTTON 0x02 #define MK_MBUTTON 0x10 - #define IDC_SIZENESW MAKEINTRESOURCE(32643) #define IDC_SIZENWSE MAKEINTRESOURCE(32642) #define IDC_IBEAM MAKEINTRESOURCE(32513) From 64b7831296b0681164f6eb8677ed2fa24d9e5b41 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 8 Aug 2018 17:24:58 -0400 Subject: [PATCH 108/144] swell-generic: fix listview clipping with status images -- from a8f1448e --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 41f66379..342f823f 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -4531,7 +4531,7 @@ static LRESULT listViewWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa { if (ncols > 0) { - ar.right = ar.left + cols[col].xwid - SWELL_UI_SCALE(3); + ar.right = xpos + cols[col].xwid - SWELL_UI_SCALE(3); xpos += cols[col].xwid; } else ar.right = cr.right; From d75784031cf3b89d77dbe82e1766a89394ee9460 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 12 Aug 2018 14:12:34 -0400 Subject: [PATCH 109/144] jnetlib: always call shutdown() before calling closesocket() -- from 964211e1 --- WDL/eel2/eel_net.h | 10 +++++++++- WDL/jnetlib/listen.cpp | 3 +++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/WDL/eel2/eel_net.h b/WDL/eel2/eel_net.h index 91c49aa7..c58a1e0e 100644 --- a/WDL/eel2/eel_net.h +++ b/WDL/eel2/eel_net.h @@ -106,6 +106,7 @@ eel_net_state::~eel_net_state() for (x=0;xsock = s; return 1; } + shutdown(s, SHUT_RDWR); closesocket(s); return 0; } diff --git a/WDL/jnetlib/listen.cpp b/WDL/jnetlib/listen.cpp index df20f1c7..03efd61d 100644 --- a/WDL/jnetlib/listen.cpp +++ b/WDL/jnetlib/listen.cpp @@ -30,6 +30,7 @@ JNL_Listen::JNL_Listen(short port, unsigned int which_interface) sin.sin_addr.s_addr = which_interface?which_interface:INADDR_ANY; if (::bind(m_socket,(struct sockaddr *)&sin,sizeof(sin))) { + shutdown(m_socket, SHUT_RDWR); closesocket(m_socket); m_socket=INVALID_SOCKET; } @@ -37,6 +38,7 @@ JNL_Listen::JNL_Listen(short port, unsigned int which_interface) { if (::listen(m_socket,8)==-1) { + shutdown(m_socket, SHUT_RDWR); closesocket(m_socket); m_socket=INVALID_SOCKET; } @@ -48,6 +50,7 @@ JNL_Listen::~JNL_Listen() { if (m_socket!=INVALID_SOCKET) { + shutdown(m_socket, SHUT_RDWR); closesocket(m_socket); } } From 8489fe04c3995a821bc8fd644bf35efec9dc4ed0 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 12 Aug 2018 15:20:00 -0400 Subject: [PATCH 110/144] swell/lice: read /proc/self/exe rather than /proc//exe -- from d9a2488a --- WDL/lice/lice_png.cpp | 4 +--- WDL/swell/swell-modstub-generic.cpp | 4 +--- WDL/swell/swell.cpp | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/WDL/lice/lice_png.cpp b/WDL/lice/lice_png.cpp index bf08efee..3eae5e1a 100644 --- a/WDL/lice/lice_png.cpp +++ b/WDL/lice/lice_png.cpp @@ -184,9 +184,7 @@ LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp) if (!buf[0]) return 0; strcat(buf,"/Contents/Resources/"); #else - char tmp[64]; - sprintf(tmp,"/proc/%d/exe",getpid()); - int sz = readlink(tmp, buf, sizeof(buf)-512); + int sz = readlink("/proc/self/exe", buf, sizeof(buf)-512); if (sz<0) sz=0; else if (sz >= sizeof(buf)-512) sz = sizeof(buf)-512-1; buf[sz]=0; diff --git a/WDL/swell/swell-modstub-generic.cpp b/WDL/swell/swell-modstub-generic.cpp index 3aa9e3f5..b48845f0 100644 --- a/WDL/swell/swell-modstub-generic.cpp +++ b/WDL/swell/swell-modstub-generic.cpp @@ -78,9 +78,7 @@ class SwellAPPInitializer void *(*SWELLAPI_GetFunc)(const char *name)=NULL; char fn[4096]; const int nSize=sizeof(fn)-64; - char lnk[64]; - sprintf(lnk,"/proc/%d/exe",getpid()); - int sz=readlink(lnk,fn,nSize); + int sz=readlink("/proc/self/exe",fn,nSize); if (sz<0)sz=0; else if (sz>=nSize)sz=nSize-1; fn[sz]=0; diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index aef145c1..4dbec57d 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -920,9 +920,7 @@ DWORD GetModuleFileName(HINSTANCE hInst, char *fn, DWORD nSize) #elif defined(__linux__) if (!instptr) // get exe file name { - char tmp[64]; - sprintf(tmp,"/proc/%d/exe",getpid()); - int sz=readlink(tmp,fn,nSize); + int sz=readlink("/proc/self/exe",fn,nSize); if (sz<0)sz=0; else if ((DWORD)sz>=nSize)sz=nSize-1; fn[sz]=0; From 055b4cb379a8276987bcf971768943ec7a0911b4 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 12 Aug 2018 15:31:11 -0400 Subject: [PATCH 111/144] swell-linux: try to find libSwell.so even if /proc/self/exe is not available swell-linux: fallback to dladdr() if /proc/self/exe is unavailable -- from 69ebcf09 --- WDL/lice/lice_png.cpp | 15 +++++++++++++-- WDL/swell/swell-modstub-generic.cpp | 14 +++++++++++--- WDL/swell/swell.cpp | 14 ++++++++++++-- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/WDL/lice/lice_png.cpp b/WDL/lice/lice_png.cpp index 3eae5e1a..c5e02133 100644 --- a/WDL/lice/lice_png.cpp +++ b/WDL/lice/lice_png.cpp @@ -185,8 +185,19 @@ LICE_IBitmap *LICE_LoadPNGFromNamedResource(const char *name, LICE_IBitmap *bmp) strcat(buf,"/Contents/Resources/"); #else int sz = readlink("/proc/self/exe", buf, sizeof(buf)-512); - if (sz<0) sz=0; - else if (sz >= sizeof(buf)-512) sz = sizeof(buf)-512-1; + if (sz < 1) + { + static char tmp; + // this will likely not work if the program was launched with a relative path + // and the cwd has changed, but give it a try anyway + Dl_info inf={0,}; + if (dladdr(&tmp,&inf) && inf.dli_fname) + sz = (int) strlen(inf.dli_fname); + else + sz = 0; + } + + if (sz >= sizeof(buf)-512) sz = sizeof(buf)-512-1; buf[sz]=0; char *p = buf; while (*p) p++; diff --git a/WDL/swell/swell-modstub-generic.cpp b/WDL/swell/swell-modstub-generic.cpp index b48845f0..4985e4be 100644 --- a/WDL/swell/swell-modstub-generic.cpp +++ b/WDL/swell/swell-modstub-generic.cpp @@ -79,13 +79,21 @@ class SwellAPPInitializer char fn[4096]; const int nSize=sizeof(fn)-64; int sz=readlink("/proc/self/exe",fn,nSize); - if (sz<0)sz=0; - else if (sz>=nSize)sz=nSize-1; + if (sz<1) + { + Dl_info inf={0,}; + if (dladdr(&api_tab,&inf) && inf.dli_fname) + sz = (int) strlen(inf.dli_fname); + else + sz = 0; + } + if (sz>=nSize)sz=nSize-1; fn[sz]=0; char *p=fn; while (*p) p++; while (p >= fn && *p != '/') p--; - strcpy(++p,"libSwell.so"); + p++; + strcpy(p,p==fn ? "./libSwell.so" : "libSwell.so"); void *tmp = dlopen(fn,RTLD_LAZY); if (!tmp) diff --git a/WDL/swell/swell.cpp b/WDL/swell/swell.cpp index 4dbec57d..88bbb8b3 100644 --- a/WDL/swell/swell.cpp +++ b/WDL/swell/swell.cpp @@ -921,8 +921,18 @@ DWORD GetModuleFileName(HINSTANCE hInst, char *fn, DWORD nSize) if (!instptr) // get exe file name { int sz=readlink("/proc/self/exe",fn,nSize); - if (sz<0)sz=0; - else if ((DWORD)sz>=nSize)sz=nSize-1; + if (sz<1) + { + static char tmp; + // this will likely not work if the program was launched with a relative path + // and the cwd has changed, but give it a try anyway + Dl_info inf={0,}; + if (dladdr(&tmp,&inf) && inf.dli_fname) + sz = (int) strlen(inf.dli_fname); + else + sz=0; + } + if ((DWORD)sz>=nSize)sz=nSize-1; fn[sz]=0; return sz; } From 7903ee84a5e271927fa4df82722c988b96dbcafb Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 14 Aug 2018 17:30:24 -0400 Subject: [PATCH 112/144] swell-generic: file browser can show dot files/directories (toggle via context menu or Ctrl+H) --- WDL/swell/swell-miscdlg-generic.cpp | 45 +++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp index f978d322..162cfa79 100644 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -59,7 +59,7 @@ class BrowseFile_State BrowseFile_State(const char *_cap, const char *_idir, const char *_ifile, const char *_el, modeEnum _mode, char *_fnout, int _fnout_sz) : caption(_cap), initialdir(_idir), initialfile(_ifile), extlist(_el), mode(_mode), sortcol(0), sortrev(0), - fnout(_fnout), fnout_sz(_fnout_sz), viewlist_store(16384), viewlist(4096) + fnout(_fnout), fnout_sz(_fnout_sz), viewlist_store(16384), viewlist(4096), show_hidden(false) { } ~BrowseFile_State() @@ -139,6 +139,9 @@ class BrowseFile_State } WDL_TypedBuf viewlist_store; WDL_PtrList viewlist; + + bool show_hidden; + void viewlist_sort(const char *filter) { if (filter) @@ -194,7 +197,10 @@ class BrowseFile_State struct dirent *ent; while (NULL != (ent = readdir(dir))) { - if (ent->d_name[0] == '.') continue; + if (ent->d_name[0] == '.') + { + if (ent->d_name[1] == 0 || ent->d_name[1] == '.' || !show_hidden) continue; + } bool is_dir = (ent->d_type == DT_DIR); if (ent->d_type == DT_UNKNOWN) { @@ -283,7 +289,7 @@ static void preprocess_user_path(char *buf, int bufsz) static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { - enum { IDC_EDIT=0x100, IDC_LABEL, IDC_CHILD, IDC_DIR, IDC_LIST, IDC_EXT, IDC_PARENTBUTTON, IDC_FILTER }; + enum { IDC_EDIT=0x100, IDC_LABEL, IDC_CHILD, IDC_DIR, IDC_LIST, IDC_EXT, IDC_PARENTBUTTON, IDC_FILTER, ID_SHOW_HIDDEN }; enum { WM_UPD=WM_USER+100 }; const int maxPathLen = 2048; const char *multiple_files = "(multiple files)"; @@ -317,13 +323,15 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L const char *ent = parms->mode == BrowseFile_State::OPENDIR ? "dir_browser" : "file_browser"; char tmp[128]; GetPrivateProfileString(".swell",ent,"", tmp,sizeof(tmp),""); - int x=0,y=0,w=0,h=0, c1=0,c2=0,c3=0; + int x=0,y=0,w=0,h=0, c1=0,c2=0,c3=0,extraflag=0; int flag = SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; if (tmp[0] && - sscanf(tmp,"%d %d %d %d %d %d %d",&x,&y,&w,&h,&c1,&c2,&c3) >= 4) + sscanf(tmp,"%d %d %d %d %d %d %d %d",&x,&y,&w,&h,&c1,&c2,&c3,&extraflag) >= 4) flag &= ~SWP_NOMOVE; if (w < 100) w=SWELL_UI_SCALE(600); if (h < 100) h=SWELL_UI_SCALE(400); + if (extraflag&1) + parms->show_hidden=true; if (c1 + c2 + c3 < w/2) { @@ -432,7 +440,9 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L const int c2 = ListView_GetColumnWidth(list,1); const int c3 = ListView_GetColumnWidth(list,2); char tmp[128]; - snprintf(tmp,sizeof(tmp),"%d %d %d %d %d %d %d",r.left,r.top,r.right-r.left,r.bottom-r.top,c1,c2,c3); + int extraflag=0; + if (parms->show_hidden) extraflag|=1; + snprintf(tmp,sizeof(tmp),"%d %d %d %d %d %d %d %d",r.left,r.top,r.right-r.left,r.bottom-r.top,c1,c2,c3,extraflag); const char *ent = parms->mode == BrowseFile_State::OPENDIR ? "dir_browser" : "file_browser"; WritePrivateProfileString(".swell",ent, tmp, ""); } @@ -768,6 +778,13 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L } EndDialog(hwnd,1); return 0; + case ID_SHOW_HIDDEN: + { + BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); + parms->show_hidden = !parms->show_hidden; + SendMessage(hwnd,WM_UPD,1,0); + } + return 0; } break; case WM_NOTIFY: @@ -859,6 +876,11 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L SendMessage(hwnd,WM_UPD,1,0); return 1; } + else if (lParam == (FVIRTKEY|FCONTROL) && wParam == 'H') + { + SendMessage(hwnd,WM_COMMAND,ID_SHOW_HIDDEN,0); + return 1; + } else if (lParam == FVIRTKEY && wParam == VK_BACK && GetFocus() == GetDlgItem(hwnd,IDC_LIST)) { @@ -872,6 +894,17 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L return 1; } return 0; + case WM_CONTEXTMENU: + { + BrowseFile_State *parms = (BrowseFile_State *)GetWindowLongPtr(hwnd,GWLP_USERDATA); + HMENU menu = CreatePopupMenu(); + SWELL_InsertMenu(menu,0,MF_BYPOSITION|(parms->show_hidden ? MF_CHECKED:MF_UNCHECKED), ID_SHOW_HIDDEN, "Show files/directories beginning with ."); + POINT p; + GetCursorPos(&p); + TrackPopupMenu(menu,0,p.x,p.y,0,hwnd,NULL); + DestroyMenu(menu); + } + return 1; } return 0; } From 0f51a74ffa9a977c0d0d3a80ce012c3bc51ebf91 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 15 Aug 2018 09:15:09 -0400 Subject: [PATCH 113/144] swell-generic: file/directory browse tracks recent paths -- from 7bdf8168 --- WDL/swell/swell-miscdlg-generic.cpp | 91 +++++++++++++++++++++++++++-- 1 file changed, 87 insertions(+), 4 deletions(-) diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp index 162cfa79..7712fafe 100644 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -33,6 +33,7 @@ #include "../wdlcstring.h" #include "../assocarray.h" +#include "../ptrlist.h" #include #include @@ -40,6 +41,58 @@ #define WDL_HASSTRINGS_EXPORT static #include "../has_strings.h" + +#ifndef SWELL_BROWSE_RECENT_SIZE +#define SWELL_BROWSE_RECENT_SIZE 12 +#endif +static WDL_PtrList s_browse_rcu; +static void recent_addtocb(HWND hwnd) +{ + for (int x=0;x=SWELL_BROWSE_RECENT_SIZE) + s_browse_rcu.Delete(SWELL_BROWSE_RECENT_SIZE,true,free); + s_browse_rcu.Insert(0,strdup(path)); + } + if (!allowwrite) return; + + for (x=0;x<=s_browse_rcu.GetSize();x++) + { + char tmp[64]; + snprintf(tmp,sizeof(tmp),"path%d",x); + WritePrivateProfileString(".swell_recent_path",tmp, s_browse_rcu.Get(x),""); + } +} +static void recent_read() +{ + if (s_browse_rcu.GetSize()) return; + int x; + for (x=0;xinitialdir) recent_write(parms->initialdir,false); + if (parms->initialfile) + { + lstrcpyn_safe(tmp,parms->initialfile,sizeof(tmp)); + WDL_remove_filepart(tmp); + if (tmp[0]) recent_write(tmp,false); + } + if (parms->caption) SetWindowText(hwnd,parms->caption); SWELL_MakeSetCurParms(1,1,0,0,hwnd,false,false); @@ -321,7 +385,6 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L SWELL_MakeEditField(IDC_FILTER, 0,0,0,0, 0); const char *ent = parms->mode == BrowseFile_State::OPENDIR ? "dir_browser" : "file_browser"; - char tmp[128]; GetPrivateProfileString(".swell",ent,"", tmp,sizeof(tmp),""); int x=0,y=0,w=0,h=0, c1=0,c2=0,c3=0,extraflag=0; int flag = SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER; @@ -465,6 +528,7 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L WDL_remove_trailing_dirchars(path); } SendMessage(combo,CB_ADDSTRING,0,(LPARAM)"/"); + recent_addtocb(combo); SendMessage(combo,CB_SETCURSEL,0,0); } break; @@ -590,7 +654,8 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L case IDC_PARENTBUTTON: { int a = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCURSEL,0,0); - if (a>=0) + int cbcnt = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCOUNT,0,0); + if (a>=0 && a < cbcnt - s_browse_rcu.GetSize()) { SendDlgItemMessage(hwnd,IDC_DIR,CB_SETCURSEL,a+1,0); } @@ -600,7 +665,11 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L GetDlgItemText(hwnd,IDC_DIR,buf,sizeof(buf)); preprocess_user_path(buf,sizeof(buf)); WDL_remove_filepart(buf); - SetDlgItemText(hwnd,IDC_DIR,buf); + if (a>=0) + { + SendMessage(hwnd,WM_UPD,IDC_DIR,(LPARAM)buf); + return 0; + } } SendMessage(hwnd,WM_UPD,1,0); } @@ -608,7 +677,17 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L case IDC_DIR: if (HIWORD(wParam) == CBN_SELCHANGE) { - SendMessage(hwnd,WM_UPD,1,0); + int a = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCURSEL,0,0); + int cbcnt = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCOUNT,0,0); + if (a>=cbcnt - s_browse_rcu.GetSize()) + { + char buf[maxPathLen]; + GetDlgItemText(hwnd,IDC_DIR,buf,sizeof(buf)); + preprocess_user_path(buf,sizeof(buf)); + SendMessage(hwnd,WM_UPD,IDC_DIR,(LPARAM)buf); + } + else + SendMessage(hwnd,WM_UPD,1,0); } return 0; case IDCANCEL: EndDialog(hwnd,0); return 0; @@ -651,6 +730,7 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L int cnt; if (parms->mode == BrowseFile_State::OPENMULTI && (cnt=ListView_GetSelectedCount(GetDlgItem(hwnd,IDC_LIST)))>1 && (!*msg || !strcmp(msg,multiple_files))) { + recent_write(buf); HWND list = GetDlgItem(hwnd,IDC_LIST); WDL_TypedBuf fs; fs.Set(buf,strlen(buf)+1); @@ -775,6 +855,9 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L parms->fnout = (char*)calloc(l+2,1); memcpy(parms->fnout,buf,l); } + if (parms->mode != BrowseFile_State::OPENDIR) + WDL_remove_filepart(buf); + recent_write(buf); } EndDialog(hwnd,1); return 0; From 6d7f0ee6e1804e1ec234f7c6453c37e95f66e7d1 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 15 Aug 2018 09:36:50 -0400 Subject: [PATCH 114/144] swell-generic: recent list fixes, prevent initial paths from getting into persistent recent list -- from 1e047453 --- WDL/swell/swell-miscdlg-generic.cpp | 43 ++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 13 deletions(-) diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp index 7712fafe..3a653765 100644 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -45,13 +45,18 @@ #ifndef SWELL_BROWSE_RECENT_SIZE #define SWELL_BROWSE_RECENT_SIZE 12 #endif -static WDL_PtrList s_browse_rcu; +static WDL_PtrList s_browse_rcu, s_browse_rcu_tmp; +static int recent_size() { return s_browse_rcu.GetSize() + s_browse_rcu_tmp.GetSize(); } + static void recent_addtocb(HWND hwnd) { - for (int x=0;xinitialdir) recent_write(parms->initialdir,false); + + recent_add_tmp(parms->initialdir); + if (parms->initialfile) { lstrcpyn_safe(tmp,parms->initialfile,sizeof(tmp)); WDL_remove_filepart(tmp); - if (tmp[0]) recent_write(tmp,false); + recent_add_tmp(tmp); } if (parms->caption) SetWindowText(hwnd,parms->caption); @@ -655,7 +674,7 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L { int a = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCURSEL,0,0); int cbcnt = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCOUNT,0,0); - if (a>=0 && a < cbcnt - s_browse_rcu.GetSize()) + if (a>=0 && a < cbcnt - recent_size()) { SendDlgItemMessage(hwnd,IDC_DIR,CB_SETCURSEL,a+1,0); } @@ -666,10 +685,9 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L preprocess_user_path(buf,sizeof(buf)); WDL_remove_filepart(buf); if (a>=0) - { SendMessage(hwnd,WM_UPD,IDC_DIR,(LPARAM)buf); - return 0; - } + else + SetDlgItemText(hwnd,IDC_DIR,buf); } SendMessage(hwnd,WM_UPD,1,0); } @@ -679,15 +697,14 @@ static LRESULT WINAPI swellFileSelectProc(HWND hwnd, UINT uMsg, WPARAM wParam, L { int a = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCURSEL,0,0); int cbcnt = (int) SendDlgItemMessage(hwnd,IDC_DIR,CB_GETCOUNT,0,0); - if (a>=cbcnt - s_browse_rcu.GetSize()) + if (a>=cbcnt - recent_size()) { char buf[maxPathLen]; GetDlgItemText(hwnd,IDC_DIR,buf,sizeof(buf)); preprocess_user_path(buf,sizeof(buf)); SendMessage(hwnd,WM_UPD,IDC_DIR,(LPARAM)buf); } - else - SendMessage(hwnd,WM_UPD,1,0); + SendMessage(hwnd,WM_UPD,1,0); } return 0; case IDCANCEL: EndDialog(hwnd,0); return 0; From 0233af02bf1075fe48a9fafa49c9c481207740ad Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 16 Aug 2018 09:41:55 -0400 Subject: [PATCH 115/144] swell-generic: use FreeType family name for GetTextFace() (may not match the dumb swell fontmapper logic though) -- from c2789887 --- WDL/swell/swell-gdi-lice.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp index 00604a0e..8a51bcf1 100644 --- a/WDL/swell/swell-gdi-lice.cpp +++ b/WDL/swell/swell-gdi-lice.cpp @@ -454,7 +454,18 @@ HFONT CreateFontIndirect(LOGFONT *lf) int GetTextFace(HDC ctx, int nCount, LPTSTR lpFaceName) { - if (lpFaceName) lpFaceName[0]=0; + if (lpFaceName && nCount>0) lpFaceName[0]=0; +#ifdef SWELL_FREETYPE + HDC__ *ct=(HDC__*)ctx; + if (!HDC_VALID(ct) || nCount<1 || !lpFaceName || !ct->curfont) return 0; + + const FT_FaceRec *p = (const FT_FaceRec *)ct->curfont->typedata; + if (p) + { + lstrcpyn_safe(lpFaceName, p->family_name, nCount); + return 1; + } +#endif return 0; } From e20428c131bed8aa74f11abd0e309d092fe431b6 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 15 Aug 2018 23:26:01 -0400 Subject: [PATCH 116/144] swell-generic: use fontconfig when using freetype unless NOFONTCONFIG=1 is specified on the make command line -- from a3d33762 --- WDL/swell/Makefile | 4 + WDL/swell/swell-gdi-generic.cpp | 5 +- WDL/swell/swell-gdi-lice.cpp | 129 ++++++++++++++++++++++++++-- WDL/swell/swell-miscdlg-generic.cpp | 8 +- 4 files changed, 136 insertions(+), 10 deletions(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index 8ae27625..bc0ebf94 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -115,6 +115,10 @@ ifndef NOGDK ifndef PRELOAD_GDK LINKEXTRA += $(shell $(PKG_CONFIG) --libs freetype2) endif + ifndef NOFONTCONFIG + CFLAGS += -DSWELL_FONTCONFIG + LINKEXTRA += -lfontconfig + endif endif endif diff --git a/WDL/swell/swell-gdi-generic.cpp b/WDL/swell/swell-gdi-generic.cpp index d8982090..024ccded 100644 --- a/WDL/swell/swell-gdi-generic.cpp +++ b/WDL/swell/swell-gdi-generic.cpp @@ -29,6 +29,8 @@ #include "../wdlcstring.h" const char *g_swell_deffont_face = "Arial"; +int swell_last_font_filename_want; +char *swell_last_font_filename; swell_colortheme g_swell_ctheme = { #define __def_theme_ent(x,c) (c), @@ -715,7 +717,8 @@ void swell_load_color_theme(const char *fn) { char *b = strdup(np); g_swell_deffont_face = b; - while (*b>0 && !isspace(*b)) b++; + while (*b && *b != ';' && *b != '#') b++; + while (b>g_swell_deffont_face && b[-1] > 0 && isspace(b[-1])) b--; *b=0; } continue; diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp index 8a51bcf1..92f900a9 100644 --- a/WDL/swell/swell-gdi-lice.cpp +++ b/WDL/swell/swell-gdi-lice.cpp @@ -40,11 +40,15 @@ #include FT_FREETYPE_H #include FT_GLYPH_H +#ifdef SWELL_FONTCONFIG +#include +#else +#include "../dirscan.h" +#endif + static bool s_freetype_failed; static FT_Library s_freetype; // todo: TLS for multithread support? -#include "../dirscan.h" - static int utf8char(const char *ptr, unsigned short *charOut) // returns char length { const unsigned char *p = (const unsigned char *)ptr; @@ -86,8 +90,47 @@ static int utf8char(const char *ptr, unsigned short *charOut) // returns char le return 1; } -static WDL_PtrList s_freetype_fontlist; -static WDL_PtrList s_freetype_regfonts; +extern char *swell_last_font_filename; +extern int swell_last_font_filename_want; + +#ifdef SWELL_FONTCONFIG + +static FcConfig *s_fontconfig; +const char *swell_enumFontFiles(int x) +{ + if (!s_fontconfig) return NULL; + + static FcPattern *pat; + static FcObjectSet *prop; + static FcFontSet *fonts; + if (x<0) + { + if (fonts) FcFontSetDestroy(fonts); + if (prop) FcObjectSetDestroy(prop); + if (pat) FcPatternDestroy(pat); + pat=NULL; + prop=NULL; + fonts=NULL; + return NULL; + } + if (!pat) + { + pat = FcPatternCreate(); + prop = FcObjectSetBuild(FC_FAMILY, NULL); + fonts = FcFontList(s_fontconfig,pat,prop); + } + if (fonts && x < fonts->nfont) + { + FcPattern *f = fonts->fonts[x]; + FcChar8 *fn = NULL; + if (FcPatternGetString(f,FC_FAMILY,0,&fn) == FcResultMatch && fn && *fn) + return (const char *)fn; + } + + return NULL; +} + +#else const char *swell_enumFontFiles(int x) { @@ -96,6 +139,9 @@ const char *swell_enumFontFiles(int x) return s_freetype_fontlist.Get(x-n1); } + +static WDL_PtrList s_freetype_fontlist; +static WDL_PtrList s_freetype_regfonts; static const char *stristr(const char *a, const char *b) { const size_t blen = strlen(b); @@ -154,8 +200,6 @@ struct fontScoreMatched { }; -const char *swell_last_font_filename; - static FT_Face MatchFont(const char *lfFaceName, int weight, int italic, int exact) { const int fn_len = strlen(lfFaceName), ntab=2; @@ -259,8 +303,9 @@ static FT_Face MatchFont(const char *lfFaceName, int weight, int italic, int exa } return NULL; } +#endif // !SWELL_FONTCONFIG -#endif +#endif // SWELL_FREETYPE HDC SWELL_CreateMemContext(HDC hdc, int w, int h) { @@ -355,7 +400,6 @@ HGDIOBJ GetStockObject(int wh) return 0; } -#define FONTSCALE 0.9 HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, int lfWeight, char lfItalic, char lfUnderline, char lfStrikeOut, char lfCharSet, char lfOutPrecision, char lfClipPrecision, char lfQuality, char lfPitchAndFamily, const char *lfFaceName) @@ -368,13 +412,76 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, s_freetype_failed = !!FT_Init_FreeType(&s_freetype); if (s_freetype) { +#ifdef SWELL_FONTCONFIG + if (!s_fontconfig) s_fontconfig = FcInitLoadConfigAndFonts(); +#else ScanFontDirectory("/usr/share/fonts"); qsort(s_freetype_fontlist.GetList(),s_freetype_fontlist.GetSize(),sizeof(const char *),(int (*)(const void *,const void*))sortByFilePart); +#endif } } if (s_freetype) { +#ifdef SWELL_FONTCONFIG + if (!face && s_fontconfig) + { + FcPattern *pat = FcPatternCreate(); + if (pat) + { + if (lfFaceName && *lfFaceName) FcPatternAddString(pat,FC_FAMILY,(FcChar8*)lfFaceName); + if (lfWeight > 0) + { + int wt; + if (lfWeight >= FW_HEAVY) wt=FC_WEIGHT_HEAVY; + else if (lfWeight >= FW_EXTRABOLD) wt=FC_WEIGHT_EXTRABOLD; + else if (lfWeight >= FW_BOLD) wt=FC_WEIGHT_BOLD; + else if (lfWeight >= FW_SEMIBOLD) wt=FC_WEIGHT_SEMIBOLD; + else if (lfWeight >= FW_MEDIUM) wt=FC_WEIGHT_MEDIUM; + else if (lfWeight >= FW_NORMAL) wt=FC_WEIGHT_NORMAL; + else if (lfWeight >= FW_LIGHT) wt=FC_WEIGHT_LIGHT; + else if (lfWeight >= FW_EXTRALIGHT) wt=FC_WEIGHT_EXTRALIGHT; + else wt=FC_WEIGHT_THIN; + FcPatternAddInteger(pat,FC_WEIGHT,wt); + } + if (lfItalic) + FcPatternAddInteger(pat,FC_SLANT,FC_SLANT_ITALIC); + FcConfigSubstitute(s_fontconfig,pat,FcMatchPattern); + FcDefaultSubstitute(pat); + FcResult result; + FcPattern *hit = FcFontMatch(s_fontconfig,pat,&result); + if (hit) + { + FcChar8 *fn = NULL; + if (FcPatternGetString(hit,FC_FILE,0,&fn) == FcResultMatch && fn && *fn) + { + int idx=0; + if (FcPatternGetInteger(hit,FC_INDEX,0,&idx) != FcResultMatch) idx=0; + FT_New_Face(s_freetype,(const char *)fn,idx,&face); + if (face) + { + free(swell_last_font_filename); + swell_last_font_filename=NULL; + if (swell_last_font_filename_want) + { + if (!idx) + swell_last_font_filename = strdup((const char*)fn); + else + { + char tmp[1024]; + snprintf(tmp,sizeof(tmp),"%s <%d>",fn,idx); + swell_last_font_filename = strdup(tmp); + } + } + } + } + FcPatternDestroy(hit); + } + FcPatternDestroy(pat); + } + } +#else + if (!face && lfFaceName && *lfFaceName) face = MatchFont(lfFaceName,lfWeight,lfItalic,0); if (!face) @@ -423,6 +530,7 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, } } } +#endif } if (face) @@ -1707,8 +1815,13 @@ int AddFontResourceEx(LPCTSTR str, DWORD fl, void *pdv) { if (str && *str) { +#ifdef SWELL_FONTCONFIG + if (!s_fontconfig) s_fontconfig = FcInitLoadConfigAndFonts(); + return s_fontconfig && FcConfigAppFontAddFile(s_fontconfig,(const FcChar8 *)str) != FcFalse; +#else if (s_freetype_regfonts.FindSorted(str,sortByFilePart)>=0) return 0; s_freetype_regfonts.InsertSorted(strdup(str), sortByFilePart); +#endif return 1; } return 0; diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp index 3a653765..50ae5b9c 100644 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -1574,7 +1574,9 @@ struct FontChooser_State WDL_FastString lastfn; }; -extern const char *swell_last_font_filename; +extern char *swell_last_font_filename; +extern int swell_last_font_filename_want; + const char *swell_enumFontFiles(int x); int swell_getLineLength(const char *buf, int *post_skip, int wrap_maxwid, HDC hdc); @@ -1624,6 +1626,7 @@ static LRESULT WINAPI swellFontChooserProc(HWND hwnd, UINT uMsg, WPARAM wParam, *tmp=0; if (*buf) list.AddUnsorted(buf,true); } + swell_enumFontFiles(-1); // clear cache list.Resort(); FontChooser_State *cs = (FontChooser_State*)lParam; bool italics = cs->font.lfItalic!=0; @@ -1726,7 +1729,10 @@ static LRESULT WINAPI swellFontChooserProc(HWND hwnd, UINT uMsg, WPARAM wParam, r.bottom -= border*2 + buth; r.top = r.bottom - ph; + swell_last_font_filename_want++; HFONT f = CreateFontIndirect(&cs->font); + swell_last_font_filename_want--; + HBRUSH br = CreateSolidBrush(RGB(255,255,255)); FillRect(ps.hdc,&r,br); DeleteObject(br); From 2c1211eb76f361e212e2a8e55a4b8725c502f701 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 16 Aug 2018 22:11:51 -0400 Subject: [PATCH 117/144] swell-generic: cache recent font face/size font mappings and freetype faces -- from 5697079b --- WDL/swell/swell-gdi-generic.cpp | 3 +- WDL/swell/swell-gdi-lice.cpp | 124 ++++++++++++++++++++-------- WDL/swell/swell-miscdlg-generic.cpp | 5 +- 3 files changed, 90 insertions(+), 42 deletions(-) diff --git a/WDL/swell/swell-gdi-generic.cpp b/WDL/swell/swell-gdi-generic.cpp index 024ccded..2f3cd5f4 100644 --- a/WDL/swell/swell-gdi-generic.cpp +++ b/WDL/swell/swell-gdi-generic.cpp @@ -29,8 +29,7 @@ #include "../wdlcstring.h" const char *g_swell_deffont_face = "Arial"; -int swell_last_font_filename_want; -char *swell_last_font_filename; +const char *swell_last_font_filename; swell_colortheme g_swell_ctheme = { #define __def_theme_ent(x,c) (c), diff --git a/WDL/swell/swell-gdi-lice.cpp b/WDL/swell/swell-gdi-lice.cpp index 92f900a9..13b678fd 100644 --- a/WDL/swell/swell-gdi-lice.cpp +++ b/WDL/swell/swell-gdi-lice.cpp @@ -47,7 +47,7 @@ #endif static bool s_freetype_failed; -static FT_Library s_freetype; // todo: TLS for multithread support? +static FT_Library s_freetype; // todo: TLS for multithread support? -- none of the text drawing is thread safe! static int utf8char(const char *ptr, unsigned short *charOut) // returns char length { @@ -90,8 +90,38 @@ static int utf8char(const char *ptr, unsigned short *charOut) // returns char le return 1; } -extern char *swell_last_font_filename; -extern int swell_last_font_filename_want; +extern const char *swell_last_font_filename; + +#ifndef SWELL_FREETYPE_CACHE_SIZE +#define SWELL_FREETYPE_CACHE_SIZE 80 +#endif + +class fontConfigCacheEnt +{ + public: + fontConfigCacheEnt(const char *name, int flags, int w, int h, FT_Face face, const char *fndesc) + { + m_name = strdup(name); + m_flags = flags; + m_face = face; + m_w=w; + m_h=h; + m_fndesc = strdup(fndesc); + FT_Reference_Face(m_face); + } + ~fontConfigCacheEnt() + { + free(m_name); + free(m_fndesc); + FT_Done_Face(m_face); + } + + char *m_name; + char *m_fndesc; + int m_flags, m_w, m_h; + FT_Face m_face; +}; + #ifdef SWELL_FONTCONFIG @@ -132,6 +162,9 @@ const char *swell_enumFontFiles(int x) #else +static WDL_PtrList s_freetype_fontlist; +static WDL_PtrList s_freetype_regfonts; + const char *swell_enumFontFiles(int x) { const int n1 = s_freetype_regfonts.GetSize(); @@ -140,8 +173,6 @@ const char *swell_enumFontFiles(int x) } -static WDL_PtrList s_freetype_fontlist; -static WDL_PtrList s_freetype_regfonts; static const char *stristr(const char *a, const char *b) { const size_t blen = strlen(b); @@ -200,7 +231,7 @@ struct fontScoreMatched { }; -static FT_Face MatchFont(const char *lfFaceName, int weight, int italic, int exact) +static FT_Face MatchFont(const char *lfFaceName, int weight, int italic, int exact, char *matchFnOut, size_t matchFnOutSize) { const int fn_len = strlen(lfFaceName), ntab=2; WDL_PtrList *tab[ntab]= { &s_freetype_regfonts, &s_freetype_fontlist }; @@ -294,12 +325,15 @@ static FT_Face MatchFont(const char *lfFaceName, int weight, int italic, int exa for (x=0; x < matchlist.GetSize(); x ++) { const fontScoreMatched *s = matchlist.Get()+x; - swell_last_font_filename = s->fn; FT_Face face=NULL; //printf("trying '%s' for '%s' score %d,%d w %d i %d\n",s->fn,lfFaceName,s->score1,s->score2,weight,italic); FT_New_Face(s_freetype,s->fn,0,&face); - if (face) return face; + if (face) + { + lstrcpyn_safe(matchFnOut,s->fn,matchFnOutSize); + return face; + } } return NULL; } @@ -406,7 +440,6 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, { HGDIOBJ__ *font=NULL; #ifdef SWELL_FREETYPE - FT_Face face=NULL; if (!s_freetype_failed && !s_freetype) { s_freetype_failed = !!FT_Init_FreeType(&s_freetype); @@ -421,8 +454,37 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, #endif } } - if (s_freetype) + if (lfWidth<0) lfWidth=-lfWidth; + if (lfHeight<0) lfHeight=-lfHeight; + + static WDL_PtrList cache; + const int cache_flag = wdl_max(lfWeight,0) | (lfItalic ? (1<<30) : 0); + FT_Face face=NULL; + for (int x=0;xm_flags==cache_flag && + ent->m_w == lfWidth && + ent->m_h == lfHeight && + !strcmp(ent->m_name,lfFaceName?lfFaceName:"")) + { + face = ent->m_face; + swell_last_font_filename = ent->m_fndesc; + FT_Reference_Face(face); + if (x < cache.GetSize()-1) + { + cache.Delete(x); + cache.Add(ent); // make this cache entry most recent + } + break; + } + } + + if (!face && s_freetype) + { + int face_idx=0; + char face_fn[1024]; + face_fn[0]=0; #ifdef SWELL_FONTCONFIG if (!face && s_fontconfig) { @@ -455,25 +517,9 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, FcChar8 *fn = NULL; if (FcPatternGetString(hit,FC_FILE,0,&fn) == FcResultMatch && fn && *fn) { - int idx=0; - if (FcPatternGetInteger(hit,FC_INDEX,0,&idx) != FcResultMatch) idx=0; - FT_New_Face(s_freetype,(const char *)fn,idx,&face); - if (face) - { - free(swell_last_font_filename); - swell_last_font_filename=NULL; - if (swell_last_font_filename_want) - { - if (!idx) - swell_last_font_filename = strdup((const char*)fn); - else - { - char tmp[1024]; - snprintf(tmp,sizeof(tmp),"%s <%d>",fn,idx); - swell_last_font_filename = strdup(tmp); - } - } - } + if (FcPatternGetInteger(hit,FC_INDEX,0,&face_idx) != FcResultMatch) face_idx=0; + FT_New_Face(s_freetype,(const char *)fn,face_idx,&face); + if (face) lstrcpyn_safe(face_fn,(const char *)fn,sizeof(face_fn)); } FcPatternDestroy(hit); } @@ -482,7 +528,7 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, } #else - if (!face && lfFaceName && *lfFaceName) face = MatchFont(lfFaceName,lfWeight,lfItalic,0); + if (!face && lfFaceName && *lfFaceName) face = MatchFont(lfFaceName,lfWeight,lfItalic,0, face_fn, sizeof(face_fn)); if (!face) { @@ -525,12 +571,23 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, const char *l = fallbacklist[wl]; while (*l && !face) { - face = MatchFont(l,lfWeight,lfItalic,exact?-1:1); + face = MatchFont(l,lfWeight,lfItalic,exact?-1:1, face_fn, sizeof(face_fn)); l += strlen(l)+1; } } } #endif + + if (face) + { + if (face_idx) snprintf_append(face_fn,sizeof(face_fn)," <%d>",face_idx); + fontConfigCacheEnt *ce = new fontConfigCacheEnt(lfFaceName?lfFaceName:"",cache_flag,lfWidth,lfHeight,face, face_fn); + cache.Add(ce); + if (cache.GetSize()>SWELL_FREETYPE_CACHE_SIZE) cache.Delete(0,true); + swell_last_font_filename = ce->m_fndesc; + + FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi + } } if (face) @@ -539,11 +596,6 @@ HFONT CreateFont(int lfHeight, int lfWidth, int lfEscapement, int lfOrientation, font->type=TYPE_FONT; font->typedata = face; font->alpha = 1.0f; - ////unsure here - if (lfWidth<0) lfWidth=-lfWidth; - if (lfHeight<0) lfHeight=-lfHeight; - FT_Set_Char_Size(face,lfWidth*64, lfHeight*64,0,0); // 72dpi -// FT_Set_Pixel_Sizes(face,0,lfHeight); } #else font->type=TYPE_FONT; diff --git a/WDL/swell/swell-miscdlg-generic.cpp b/WDL/swell/swell-miscdlg-generic.cpp index 50ae5b9c..045715ac 100644 --- a/WDL/swell/swell-miscdlg-generic.cpp +++ b/WDL/swell/swell-miscdlg-generic.cpp @@ -1574,8 +1574,7 @@ struct FontChooser_State WDL_FastString lastfn; }; -extern char *swell_last_font_filename; -extern int swell_last_font_filename_want; +extern const char *swell_last_font_filename; const char *swell_enumFontFiles(int x); int swell_getLineLength(const char *buf, int *post_skip, int wrap_maxwid, HDC hdc); @@ -1729,9 +1728,7 @@ static LRESULT WINAPI swellFontChooserProc(HWND hwnd, UINT uMsg, WPARAM wParam, r.bottom -= border*2 + buth; r.top = r.bottom - ph; - swell_last_font_filename_want++; HFONT f = CreateFontIndirect(&cs->font); - swell_last_font_filename_want--; HBRUSH br = CreateSolidBrush(RGB(255,255,255)); FillRect(ps.hdc,&r,br); From 4eb7a61f0a549697da364fdb2f594bde96e03801 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 19 Aug 2018 09:33:48 -0400 Subject: [PATCH 118/144] swell-generic-gdk: emulate WM_MOUSEACTIVATE, crudely -- from f4104bb9 --- WDL/swell/swell-generic-gdk.cpp | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index a7b415c2..0d220353 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -1061,6 +1061,8 @@ static void OnScrollEvent(GdkEventScroll *b) } } +static DWORD s_last_focus_change_time; + static void OnButtonEvent(GdkEventButton *b) { HWND hwnd = swell_oswindow_to_hwnd(b->window); @@ -1075,13 +1077,27 @@ static void OnButtonEvent(GdkEventButton *b) int msg=WM_LBUTTONDOWN; if (b->button==2) msg=WM_MBUTTONDOWN; else if (b->button==3) msg=WM_RBUTTONDOWN; - + + if (hwnd2) hwnd2->Retain(); + + if (b->type == GDK_BUTTON_PRESS) + { + DWORD now = GetTickCount();; + HWND oldFocus=GetFocus(); + if (!oldFocus || + oldFocus != hwnd2 || + (now >= s_last_focus_change_time && now < (s_last_focus_change_time+500))) + { + if (IsWindowEnabled(hwnd2)) + SendMessage(hwnd2,WM_MOUSEACTIVATE,0,0); + } + } + if (hwnd && hwnd->m_oswindow && SWELL_focused_oswindow != hwnd->m_oswindow) { SWELL_focused_oswindow = hwnd->m_oswindow; } - if (hwnd2) hwnd2->Retain(); // for doubleclicks, GDK actually seems to send: // GDK_BUTTON_PRESS, GDK_BUTTON_RELEASE, @@ -1303,6 +1319,7 @@ static void swell_gdkEventHandler(GdkEvent *evt, gpointer data) } if (fc->in && is_our_oswindow(fc->window)) { + s_last_focus_change_time = GetTickCount(); swell_on_toplevel_raise(fc->window); SWELL_focused_oswindow = fc->window; if (swell_app_is_inactive) From 9808b3584956c68eec36c2ffb2612ecc8690076d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 19 Aug 2018 09:40:53 -0400 Subject: [PATCH 119/144] swell-gdk: get ready to remove an old bit of code, maybe -- from 81196e94 --- WDL/swell/swell-generic-gdk.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index 0d220353..0efa29eb 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -1095,6 +1095,8 @@ static void OnButtonEvent(GdkEventButton *b) if (hwnd && hwnd->m_oswindow && SWELL_focused_oswindow != hwnd->m_oswindow) { + // this should not be necessary, focus is sent via separate events + printf("swell-generic: button event sent to non-focused window, report this message to support@cockos.com with the subject swell-gdk, thank you!\n"); SWELL_focused_oswindow = hwnd->m_oswindow; } From d88b963bc3ffc661b9b359e070267bf45c8d5870 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 2 Aug 2018 15:50:33 -0400 Subject: [PATCH 120/144] eel2: add NSEEL_VM_set_var_resolver (allows custom pointers to EEL_F variables without having to register -- resolver is only ever called at compile-time) -- from 07e88b73 --- WDL/eel2/ns-eel-int.h | 3 +++ WDL/eel2/ns-eel.h | 1 + WDL/eel2/nseel-compiler.c | 15 +++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/WDL/eel2/ns-eel-int.h b/WDL/eel2/ns-eel-int.h index 9f74f7b1..e45f78a1 100644 --- a/WDL/eel2/ns-eel-int.h +++ b/WDL/eel2/ns-eel-int.h @@ -209,6 +209,9 @@ typedef struct _compileContext EEL_F (*onString)(void *caller_this, struct eelStringSegmentRec *list); EEL_F (*onNamedString)(void *caller_this, const char *name); + EEL_F *(*getVariable)(void *userctx, const char *name); + void *getVariable_userctx; + codeHandleType *tmpCodeHandle; struct diff --git a/WDL/eel2/ns-eel.h b/WDL/eel2/ns-eel.h index 8b125c8f..d8eeb204 100644 --- a/WDL/eel2/ns-eel.h +++ b/WDL/eel2/ns-eel.h @@ -136,6 +136,7 @@ void NSEEL_VM_enumallvars(NSEEL_VMCTX ctx, int (*func)(const char *name, EEL_F * EEL_F *NSEEL_VM_regvar(NSEEL_VMCTX ctx, const char *name); // register a variable (before compilation) EEL_F *NSEEL_VM_getvar(NSEEL_VMCTX ctx, const char *name); // get a variable (if registered or created by code) int NSEEL_VM_get_var_refcnt(NSEEL_VMCTX _ctx, const char *name); // returns -1 if not registered, or >=0 +void NSEEL_VM_set_var_resolver(NSEEL_VMCTX ctx, EEL_F *(*res)(void *userctx, const char *name), void *userctx); void NSEEL_VM_freeRAM(NSEEL_VMCTX ctx); // clears and frees all (VM) RAM used void NSEEL_VM_freeRAMIfCodeRequested(NSEEL_VMCTX); // call after code to free the script-requested memory diff --git a/WDL/eel2/nseel-compiler.c b/WDL/eel2/nseel-compiler.c index 01c62c35..3aa7b3d5 100644 --- a/WDL/eel2/nseel-compiler.c +++ b/WDL/eel2/nseel-compiler.c @@ -5355,6 +5355,12 @@ EEL_F *nseel_int_register_var(compileContext *ctx, const char *name, int isReg, int wb; int ti=0; + if (isReg == 0 && ctx->getVariable) + { + EEL_F *ret = ctx->getVariable(ctx->getVariable_userctx, name); + if (ret) return ret; + } + if (!strnicmp(name,"_global.",8) && name[8]) { EEL_F *a=get_global_var(ctx,name+8,isReg >= 0); @@ -5652,3 +5658,12 @@ opcodeRec *nseel_translate(compileContext *ctx, const char *tmp, size_t tmplen) return nseel_createCompiledValue(ctx,(EEL_F)atof(tmp)); } +void NSEEL_VM_set_var_resolver(NSEEL_VMCTX _ctx, EEL_F *(*res)(void *userctx, const char *name), void *userctx) +{ + compileContext *ctx = (compileContext *)_ctx; + if (ctx) + { + ctx->getVariable = res; + ctx->getVariable_userctx = userctx; + } +} From 13ccded58140d5802e604230b2da903c1c48b3fa Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 4 Aug 2018 14:59:59 -0400 Subject: [PATCH 121/144] eel_lice: clear framebuffer-dirty flag when updating, allow EEL_LICE_WANT_STANDALONE_UPDATE_NO_SETUPFRAME -- from e7615b1e --- WDL/eel2/eel_lice.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index 3cb1e06b..05613a27 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -1898,6 +1898,7 @@ static EEL_F * NSEEL_CGEN_CALL _gfx_update(void *opaque, EEL_F *n) #ifdef __APPLE__ SWELL_QuitAutoRelease(p); #endif + ctx->m_framebuffer_dirty = 0; } // run message pump #ifndef EEL_LICE_WANT_STANDALONE_UPDATE_NO_MSGPUMP @@ -1914,9 +1915,11 @@ static EEL_F * NSEEL_CGEN_CALL _gfx_update(void *opaque, EEL_F *n) SWELL_RunEvents(); #endif #endif +#ifndef EEL_LICE_WANT_STANDALONE_UPDATE_NO_SETUPFRAME RECT r; GetClientRect(ctx->hwnd_standalone,&r); ctx->setup_frame(ctx->hwnd_standalone,r); +#endif } } return n; From 727f9124162bf976d94ec5027be2995ebfaa0fbc Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 19 Aug 2018 16:12:13 -0400 Subject: [PATCH 122/144] swell-generic: support make DEBUG_INFO=1 to include debug info in release builds -- from 85a9bb7c --- WDL/swell/Makefile | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/WDL/swell/Makefile b/WDL/swell/Makefile index bc0ebf94..303b6f3b 100644 --- a/WDL/swell/Makefile +++ b/WDL/swell/Makefile @@ -51,8 +51,12 @@ ifdef DEBUG CFLAGS += -O0 -g -D_DEBUG else CFLAGS += -O2 -DNDEBUG - ifneq ($(COMPILER),CLANG) - CFLAGS += -s + ifdef DEBUG_INFO + CFLAGS += -g + else + ifneq ($(COMPILER),CLANG) + CFLAGS += -s + endif endif endif From d269f0bdec5f28649f18e60c1ae8c831149f4a98 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 19 Aug 2018 23:07:04 -0400 Subject: [PATCH 123/144] swell-generic: set listview arrow directions to be consistent with other OSes -- from c9359378 --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 342f823f..ac1c5596 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -4603,7 +4603,7 @@ static LRESULT listViewWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lPa const int x1 = tr.left + 2; int y2 = (tr.bottom+tr.top)/2 - tsz/2 - tsz/4; int y1 = y2 + tsz; - if (cols[col].sortindicator < 0) + if (cols[col].sortindicator >= 0) { int tmp=y1; y1=y2; From 8f2a08831ca9c445164ba2e4088adf997fd315ad Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 19 Aug 2018 23:35:14 -0400 Subject: [PATCH 124/144] swell-generic: remove a printf() that was silly -- from b5d6710c --- WDL/swell/swell-generic-gdk.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-generic-gdk.cpp b/WDL/swell/swell-generic-gdk.cpp index 0efa29eb..71580665 100644 --- a/WDL/swell/swell-generic-gdk.cpp +++ b/WDL/swell/swell-generic-gdk.cpp @@ -1096,7 +1096,8 @@ static void OnButtonEvent(GdkEventButton *b) if (hwnd && hwnd->m_oswindow && SWELL_focused_oswindow != hwnd->m_oswindow) { // this should not be necessary, focus is sent via separate events - printf("swell-generic: button event sent to non-focused window, report this message to support@cockos.com with the subject swell-gdk, thank you!\n"); + // (the only time I've ever seen this is when launching a popup menu via the mousedown handler, on the mouseup + // the menu has not yet been focused but the mouse event goes to the popup menu) SWELL_focused_oswindow = hwnd->m_oswindow; } From 6bd8b0168d472b0f83f4311244671fe5bc5e90c4 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 23 Aug 2018 21:57:02 -0400 Subject: [PATCH 125/144] eel_lice: improve reascript-used mode for gfx_update() -- from fe94bfbd --- WDL/eel2/eel_lice.h | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/WDL/eel2/eel_lice.h b/WDL/eel2/eel_lice.h index 05613a27..f02a0a79 100644 --- a/WDL/eel2/eel_lice.h +++ b/WDL/eel2/eel_lice.h @@ -258,6 +258,7 @@ class eel_lice_state void *m_user_ctx; int setup_frame(HWND hwnd, RECT r, int _mouse_x=0, int _mouse_y=0); // mouse_x/y used only if hwnd is NULL + void finish_draw(); void gfx_lineto(EEL_F xpos, EEL_F ypos, EEL_F aaflag); void gfx_rectto(EEL_F xpos, EEL_F ypos); @@ -1828,6 +1829,24 @@ int eel_lice_state::setup_frame(HWND hwnd, RECT r, int _mouse_x, int _mouse_y) return dr; } +void eel_lice_state::finish_draw() +{ + if (hwnd_standalone && m_framebuffer_dirty) + { +#ifdef __APPLE__ + void *p = SWELL_InitAutoRelease(); +#endif + + InvalidateRect(hwnd_standalone,NULL,FALSE); + UpdateWindow(hwnd_standalone); + +#ifdef __APPLE__ + SWELL_QuitAutoRelease(p); +#endif + m_framebuffer_dirty = 0; + } +} + #ifndef EEL_LICE_NO_REGISTER void eel_lice_register() { @@ -1886,20 +1905,10 @@ static EEL_F * NSEEL_CGEN_CALL _gfx_update(void *opaque, EEL_F *n) ctx->m_ddrop_files.Empty(true,free); if (ctx->hwnd_standalone) { - if (ctx->m_framebuffer_dirty) - { -#ifdef __APPLE__ - void *p = SWELL_InitAutoRelease(); +#ifndef EEL_LICE_WANT_STANDALONE_UPDATE_NO_SETUPFRAME + ctx->finish_draw(); #endif - InvalidateRect(ctx->hwnd_standalone,NULL,FALSE); - UpdateWindow(ctx->hwnd_standalone); - -#ifdef __APPLE__ - SWELL_QuitAutoRelease(p); -#endif - ctx->m_framebuffer_dirty = 0; - } // run message pump #ifndef EEL_LICE_WANT_STANDALONE_UPDATE_NO_MSGPUMP From 816fb2c11f7c809122b9b8a63745c8362537eed2 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 23 Aug 2018 22:13:59 -0400 Subject: [PATCH 126/144] swell-generic: vertically center text in menu bar -- from 5dbdc51b --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index ac1c5596..d89b0a88 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6747,7 +6747,7 @@ LRESULT DefWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) dis ? g_swell_ctheme.menubar_text_disabled : g_swell_ctheme.menubar_text); - DrawText(dc,inf->dwTypeData,-1,&cr,DT_BOTTOM|DT_LEFT); + DrawText(dc,inf->dwTypeData,-1,&cr,DT_VCENTER|DT_LEFT); xpos=cr.right+g_swell_ctheme.menubar_spacing_width; } } From bd3c4d4ff4b5ec9e49bd22a6c85ac1e5884e4c6e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 26 Aug 2018 20:37:53 -0400 Subject: [PATCH 127/144] eel_mdct(): fix concurrency bug, thanks to Lauri Liinat -- from 21ed446d --- WDL/eel2/eel_mdct.h | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/WDL/eel2/eel_mdct.h b/WDL/eel2/eel_mdct.h index fd0eb3ed..0800fc3a 100644 --- a/WDL/eel2/eel_mdct.h +++ b/WDL/eel2/eel_mdct.h @@ -22,7 +22,6 @@ typedef struct { int log2n; EEL_F *trig; int *bitrev; - EEL_F *oldw; EEL_F scale; EEL_F *window; } mdct_lookup; @@ -393,7 +392,7 @@ static void *megabuf_mdct_init(int n) { int i; EEL_F c = (PI / (EEL_F) n); int *bitrev; - EEL_F *T, *oldw; + EEL_F *T; int n2, log2n; if (!lookup) return 0; @@ -415,10 +414,6 @@ static void *megabuf_mdct_init(int n) { lookup->trig = T; if (!T) return lookup; - oldw = (EEL_F*)calloc(n, sizeof(EEL_F)); - lookup->oldw = oldw; - if (!oldw) return lookup; - n2 = n >> 1; log2n = lookup->log2n = (int)(log((double)n) / log(2.0) + 0.5); @@ -459,7 +454,7 @@ static void megabuf_mdct_backward(void *init, EEL_F *in, EEL_F *out) { EEL_F *iX, *oX, *T; if (!lookup) return; n = lookup->n; - if (n <= 32 || !lookup->bitrev || !lookup->trig || !lookup->oldw) + if (n <= 32 || !lookup->bitrev || !lookup->trig) { imdct(in, out, n); return; @@ -562,11 +557,11 @@ static void megabuf_mdct_backward(void *init, EEL_F *in, EEL_F *out) { static void megabuf_mdct_forward(void *init, EEL_F *in, EEL_F *out) { mdct_lookup *lookup = (mdct_lookup *)init; int n, n2, n4, n8; - EEL_F *oldw, *w, *w2; + EEL_F *w, *w2; if (!lookup) return; n = lookup->n; - if (n <= 32 || !lookup->bitrev || !lookup->trig || !lookup->oldw) + if (n <= 32 || !lookup->bitrev || !lookup->trig) { mdct(in, out, n); return; @@ -574,7 +569,7 @@ static void megabuf_mdct_forward(void *init, EEL_F *in, EEL_F *out) { n2 = n >> 1; n4 = n >> 2; n8 = n >> 3; - oldw = lookup->oldw; + EEL_F oldw[1< Date: Mon, 27 Aug 2018 10:32:13 -0400 Subject: [PATCH 128/144] swell-generic: support right/centered text label controls -- from 1e69324f --- WDL/swell/swell-wnd-generic.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index d89b0a88..cb11c812 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -3114,7 +3114,10 @@ static LRESULT WINAPI labelWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM buf = NULL; } } - if (buf) DrawText(ps.hdc,buf,-1,&r,((hwnd->m_style & SS_CENTER) ? DT_CENTER:0)|DT_VCENTER); + if (buf) DrawText(ps.hdc,buf,-1,&r, + ((hwnd->m_style & SS_CENTER) ? DT_CENTER : + (hwnd->m_style & SS_RIGHT) ? DT_RIGHT : 0)| + DT_VCENTER); } EndPaint(hwnd,&ps); } @@ -3552,6 +3555,8 @@ HWND SWELL_MakeLabel( int align, const char *label, int idx, int x, int y, int w RECT tr=MakeCoords(x,y,w,h,true); HWND hwnd = new HWND__(m_make_owner,idx,&tr,label, !(flags&SWELL_NOT_WS_VISIBLE),labelWindowProc); hwnd->m_classname = "static"; + if (align > 0) flags |= SS_RIGHT; + else if (align == 0) flags |= SS_CENTER; hwnd->m_style = (flags & ~SWELL_NOT_WS_VISIBLE)|WS_CHILD; hwnd->m_wantfocus = false; hwnd->m_wndproc(hwnd,WM_CREATE,0,0); From d522b1ef54241c0b5a8a7c3eba29b1cdc4665f6e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 28 Aug 2018 19:36:35 +0100 Subject: [PATCH 129/144] swell-generic: setting text for an auto-hscroll, single line, non-focused edit control will auto-scroll to the start of that text -- from d1e8e110 --- WDL/swell/swell-wnd-generic.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index cb11c812..4dc6b818 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -2800,6 +2800,9 @@ static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM es->cursor_pos = WDL_utf8_get_charlen(hwnd->m_title.Get()); es->sel1=es->sel2=-1; es->cache_linelen_w=es->cache_linelen_strlen=0; + if ((hwnd->m_style & (ES_MULTILINE|ES_AUTOHSCROLL))==ES_AUTOHSCROLL && + GetFocus() != hwnd) + es->autoScrollToOffset(hwnd,0,false,false); } InvalidateRect(hwnd,NULL,FALSE); if (hwnd->m_id && hwnd->m_parent) From 89fb48fcb729df979c1f2ade32820a859280c570 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Tue, 28 Aug 2018 21:44:35 +0100 Subject: [PATCH 130/144] swell-generic: improve edit control autoscroll behavior when replacing text -- from 4c439d8d --- WDL/swell/swell-wnd-generic.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 4dc6b818..1d2d53a6 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -2626,6 +2626,8 @@ static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM return 0; case WM_KEYDOWN: { + const int osel1 = es && es->sel1 >= 0 && es->sel2 > es->sel1 ? es->sel1 : -1; + int f = OnEditKeyDown(hwnd,msg,wParam,lParam, !!(hwnd->m_style&ES_WANTRETURN), !!(hwnd->m_style&ES_MULTILINE), @@ -2639,6 +2641,10 @@ static LRESULT WINAPI editWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM } if (f&2) { + if ((hwnd->m_style & (ES_MULTILINE|ES_AUTOHSCROLL)) == ES_AUTOHSCROLL && + osel1 >= 0 && es->cursor_pos > osel1 && es->sel1 < 0) + es->autoScrollToOffset(hwnd,osel1,false,false); + es->autoScrollToOffset(hwnd,es->cursor_pos, (hwnd->m_style & ES_MULTILINE) != 0, (hwnd->m_style & (ES_MULTILINE|ES_AUTOHSCROLL)) == ES_MULTILINE From 2dfa12c3e9fee370c266e2bb0ac26f848629bc43 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 15 Sep 2018 11:49:50 -0400 Subject: [PATCH 131/144] swell-generic: fix WindowFromPoint() incorrect handling of owned windows -- from 920ad16b --- WDL/swell/swell-wnd-generic.cpp | 35 +++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 1d2d53a6..dbdbd3b7 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6300,6 +6300,31 @@ HWND ChildWindowFromPoint(HWND h, POINT p) return h; } +static HWND recurseOwnedWindowHitTest(HWND h, POINT p, int maxdepth) +{ + RECT r; + GetWindowContentViewRect(h,&r); + if (!PtInRect(&r,p)) return NULL; + + // check any owned windows first, as they are always above our window + if (h->m_owned_list && maxdepth > 0) + { + HWND owned = h->m_owned_list; + while (owned) + { + if (owned->m_visible) + { + HWND hit = recurseOwnedWindowHitTest(owned,p,maxdepth-1); + if (hit) return hit; + } + owned = h->m_owned_next; + } + } + p.x -= r.left; + p.y -= r.top; + return ChildWindowFromPoint(h,p); +} + HWND WindowFromPoint(POINT p) { HWND h = SWELL_topwindows; @@ -6307,14 +6332,8 @@ HWND WindowFromPoint(POINT p) { if (h->m_visible) { - RECT r; - GetWindowContentViewRect(h,&r); - if (PtInRect(&r,p)) - { - p.x -= r.left; - p.y -= r.top; - return ChildWindowFromPoint(h,p); - } + HWND hit = recurseOwnedWindowHitTest(h,p,20); + if (hit) return hit; } h = h->m_next; } From 1308c6b41bbcbce2407ede6545c1e864d2817c2b Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 15 Sep 2018 13:10:23 -0400 Subject: [PATCH 132/144] virtwnd-slider: fix issue on -generic when going from non-precise mode to precise mode -- from 00289bdb --- WDL/wingui/virtwnd-slider.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WDL/wingui/virtwnd-slider.cpp b/WDL/wingui/virtwnd-slider.cpp index 5891e22f..e04cf4f0 100644 --- a/WDL/wingui/virtwnd-slider.cpp +++ b/WDL/wingui/virtwnd-slider.cpp @@ -980,6 +980,9 @@ void WDL_VirtualSlider::OnMoveOrUp(int xpos, int ypos, int isup) m_last_y=ypos; m_last_x=xpos; while (m_last_precmode>0) {m_last_precmode--; ShowCursor(TRUE); } +#if !defined(_WIN32) && !defined(__APPLE__) + GetCursorPos(&s_lastmousepos); +#endif } m_needflush=0; } From 03df55ad7c7295579ddc4dfe78cb45ab48384065 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 16 Sep 2018 19:33:24 -0400 Subject: [PATCH 133/144] swell-generic: fix typo in recurseOwnedWindowHitTest() -- from 42ab1ed0 --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index dbdbd3b7..7fb339e7 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6317,7 +6317,7 @@ static HWND recurseOwnedWindowHitTest(HWND h, POINT p, int maxdepth) HWND hit = recurseOwnedWindowHitTest(owned,p,maxdepth-1); if (hit) return hit; } - owned = h->m_owned_next; + owned = owned->m_owned_next; } } p.x -= r.left; From 35e975bde586cb7a26c430699a6fa6fe03920ead Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 16 Sep 2018 19:38:12 -0400 Subject: [PATCH 134/144] swell-generic: fix ListView_HitTest() for out of range areas (thanks cfillion) -- from d4951648 --- WDL/swell/swell-wnd-generic.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 7fb339e7..158febe3 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -6092,7 +6092,7 @@ int ListView_HitTest(HWND h, LVHITTESTINFO *pinf) const int ypos = y - lvs->GetColumnHeaderHeight(h); const int hit = ypos >= 0 ? ((ypos + lvs->m_scroll_y) / lvs->m_last_row_height) : -1; if (hit < 0) pinf->flags |= LVHT_ABOVE; - pinf->iItem=hit; + pinf->iItem=hit < 0 || hit >= lvs->GetNumItems() ? -1 : hit; if (pinf->iItem >= 0) { if (lvs->m_status_imagelist && x < lvs->m_last_row_height) From fc58302201eda128962e4b7aaec7e033a54b5f28 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Fri, 21 Sep 2018 00:19:04 -0400 Subject: [PATCH 135/144] swell-generic: add GetClassName() -- from 10804876 --- WDL/swell/swell-functions.h | 1 + WDL/swell/swell-wnd-generic.cpp | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/WDL/swell/swell-functions.h b/WDL/swell/swell-functions.h index 75fa11fa..fba83c64 100644 --- a/WDL/swell/swell-functions.h +++ b/WDL/swell/swell-functions.h @@ -1064,6 +1064,7 @@ SWELL_API_DEFINE(void,SWELL_Register_Cursor_Resource,(const char *idx, const cha #ifndef SWELL_TARGET_OSX SWELL_API_DEFINE(bool, SWELL_ChooseColor, (HWND, int *, int ncustom, int *custom)) SWELL_API_DEFINE(bool, SWELL_ChooseFont, (HWND, LOGFONT*)) +SWELL_API_DEFINE(int, GetClassName, (HWND, char *, int)) #endif SWELL_API_DEFINE(bool, IsWindowEnabled, (HWND)) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 158febe3..68e9e7c3 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -7803,6 +7803,12 @@ int swell_fullscreenWindow(HWND hwnd, BOOL fs) return 0; } +int GetClassName(HWND hwnd, char *buf, int bufsz) +{ + if (!hwnd || !hwnd->m_classname || !buf || bufsz<1) return 0; + lstrcpyn_safe(buf,hwnd->m_classname,bufsz); + return (int)strlen(buf); +} #ifdef _DEBUG void VALIDATE_HWND_LIST(HWND listHead, HWND par) From e7fcd47ef7da4d2db8038a39f4d6b300947e9a1d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 23 Sep 2018 11:03:33 -0400 Subject: [PATCH 136/144] SWELL: support GetClassName() on macOS, support SWELL_SetClassName() for setting window class names of swell-created windows -- from bba74316 --- WDL/swell/swell-dlg.mm | 9 ++++--- WDL/swell/swell-functions.h | 4 ++- WDL/swell/swell-internal.h | 2 ++ WDL/swell/swell-wnd-generic.cpp | 6 +++++ WDL/swell/swell-wnd.mm | 47 +++++++++++++++++++++++++-------- 5 files changed, 52 insertions(+), 16 deletions(-) diff --git a/WDL/swell/swell-dlg.mm b/WDL/swell/swell-dlg.mm index f7abc4ff..e4b1ab7b 100644 --- a/WDL/swell/swell-dlg.mm +++ b/WDL/swell/swell-dlg.mm @@ -983,6 +983,7 @@ - (id)initChild:(SWELL_DialogResourceIndex *)resstate Parent:(NSView *)parent dl NSRect contentRect=NSMakeRect(0,0,resstate ? resstate->width : 300,resstate ? resstate->height : 200); if (!(self = [super initWithFrame:contentRect])) return self; + m_classname=NULL; memset(m_access_cacheptrs,0,sizeof(m_access_cacheptrs)); m_allow_nomiddleman=1; m_isdirty=3; @@ -1782,10 +1783,10 @@ - (BOOL)accessibilityIsIgnored return [super accessibilityIsIgnored]; } - - - - +- (const char *)getSwellClass +{ + return m_classname; +} @end diff --git a/WDL/swell/swell-functions.h b/WDL/swell/swell-functions.h index fba83c64..f1c7cf2a 100644 --- a/WDL/swell/swell-functions.h +++ b/WDL/swell/swell-functions.h @@ -1064,9 +1064,11 @@ SWELL_API_DEFINE(void,SWELL_Register_Cursor_Resource,(const char *idx, const cha #ifndef SWELL_TARGET_OSX SWELL_API_DEFINE(bool, SWELL_ChooseColor, (HWND, int *, int ncustom, int *custom)) SWELL_API_DEFINE(bool, SWELL_ChooseFont, (HWND, LOGFONT*)) -SWELL_API_DEFINE(int, GetClassName, (HWND, char *, int)) #endif SWELL_API_DEFINE(bool, IsWindowEnabled, (HWND)) +SWELL_API_DEFINE(int, GetClassName, (HWND, char *, int)) // only partially implemented, if using custom control creators they should call SWELL_SetClassName() to set the class name (reading class name is desired) +SWELL_API_DEFINE(void, SWELL_SetClassName, (HWND, const char*)) // must pass a static string! + #endif // _WDL_SWELL_H_API_DEFINED_ diff --git a/WDL/swell/swell-internal.h b/WDL/swell/swell-internal.h index 429fc84f..7b76e20a 100644 --- a/WDL/swell/swell-internal.h +++ b/WDL/swell/swell-internal.h @@ -299,6 +299,7 @@ typedef struct WindowPropRec char m_allow_nomiddleman; id m_lastTopLevelOwner; // save a copy of the owner, if any id m_access_cacheptrs[6]; + const char *m_classname; } - (id)initChild:(SWELL_DialogResourceIndex *)resstate Parent:(NSView *)parent dlgProc:(DLGPROC)dlgproc Param:(LPARAM)par; - (LRESULT)onSwellMessage:(UINT)msg p1:(WPARAM)wParam p2:(LPARAM)lParam; @@ -332,6 +333,7 @@ typedef struct WindowPropRec -(int)swellSetProp:(const char *)name value:(void *)val ; -(NSOpenGLContext *)swellGetGLContext; - (void) setEnabledSwellNoFocus; +-(const char *)getSwellClass; // NSAccessibility diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 68e9e7c3..2e637435 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -7803,6 +7803,12 @@ int swell_fullscreenWindow(HWND hwnd, BOOL fs) return 0; } +void SWELL_SetClassName(HWND hwnd, const char *p) +{ + if (hwnd) + hwnd->m_classname=p; +} + int GetClassName(HWND hwnd, char *buf, int bufsz) { if (!hwnd || !hwnd->m_classname || !buf || bufsz<1) return 0; diff --git a/WDL/swell/swell-wnd.mm b/WDL/swell/swell-wnd.mm index a90c3a48..28813ed0 100644 --- a/WDL/swell/swell-wnd.mm +++ b/WDL/swell/swell-wnd.mm @@ -56,7 +56,8 @@ static LRESULT sendSwellMessage(id obj, UINT uMsg, WPARAM wParam, LPARAM lParam) return 0; } static void InvalidateSuperViews(NSView *view); -#define STANDARD_CONTROL_NEEDSDISPLAY_IMPL \ +#define STANDARD_CONTROL_NEEDSDISPLAY_IMPL(classname) \ + - (const char *)swellGetClass { return ( classname ); } \ - (void)setNeedsDisplay:(BOOL)flag \ { \ [super setNeedsDisplay:flag]; \ @@ -160,7 +161,7 @@ static NSInteger arr_bsearch_mod(void *key, NSArray *arr, int (*compar)(const vo @implementation SWELL_TabView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("SysTabControl32") -(void)setNotificationWindow:(id)dest { @@ -190,7 +191,7 @@ - (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabVi @implementation SWELL_ProgressView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("msctls_progress32") -(NSInteger) tag { @@ -266,7 +267,7 @@ -(NSColor *)highlightColorWithFrame:(NSRect)cellFrame inView:(NSView *)controlVi @end @implementation SWELL_TreeView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("SysTreeView32") -(id) init { @@ -429,7 +430,7 @@ - (void)highlightSelectionInClipRect:(NSRect)theClipRect @implementation SWELL_ListView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL( m_lbMode ? "SysListView32_LB" : "SysListView32" ) -(LONG)getSwellStyle { return style; } @@ -1476,7 +1477,7 @@ bool IsWindowEnabled(HWND hwnd) @implementation SWELL_Button : NSButton -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("Button") -(id) init { self = [super init]; @@ -3064,7 +3065,7 @@ HWND SWELL_MakeButton(int def, const char *label, int idx, int x, int y, int w, @implementation SWELL_TextView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("Edit") -(NSInteger) tag { @@ -3175,7 +3176,7 @@ - (BOOL)becomeFirstResponder; @implementation SWELL_TextField -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL([self isSelectable] ? "Edit" : "static") - (BOOL)becomeFirstResponder; { @@ -3766,7 +3767,7 @@ HWND SWELL_MakeCombo(int idx, int x, int y, int w, int h, int flags) @implementation SWELL_BoxView -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("groupbox") -(NSInteger) tag { @@ -6020,14 +6021,14 @@ void SWELL_DrawFocusRect(HWND hwndPar, RECT *rct, void **handle) @implementation SWELL_PopUpButton -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("combobox") -(void)setSwellStyle:(LONG)style { m_style=style; } -(LONG)getSwellStyle { return m_style; } @end @implementation SWELL_ComboBox -STANDARD_CONTROL_NEEDSDISPLAY_IMPL +STANDARD_CONTROL_NEEDSDISPLAY_IMPL("combobox") -(void)setSwellStyle:(LONG)style { m_style=style; } -(LONG)getSwellStyle { return m_style; } @@ -6349,6 +6350,30 @@ BOOL SWELL_IsStaticText(HWND hwnd) return FALSE; } +void SWELL_SetClassName(HWND hwnd, const char *p) +{ + if (hwnd && [(id)hwnd isKindOfClass:[SWELL_hwndChild class]]) + ((SWELL_hwndChild *)hwnd)->m_classname=p; +} + +int GetClassName(HWND hwnd, char *buf, int bufsz) +{ + if (!hwnd || !buf || bufsz<1) return 0; + buf[0]=0; + if ([(id)hwnd respondsToSelector:@selector(getSwellClass)]) + { + const char *cn = [(SWELL_hwndChild*)hwnd getSwellClass]; + if (cn) lstrcpyn_safe(buf,cn,bufsz); + } + else + { + // default handling of other controls? + } + + return (int)strlen(buf); +} + + bool SWELL_SetAppAutoHideMenuAndDock(int ah) { From 3e22d01fecf326486522fa4909343a6bbf5a1fea Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sun, 23 Sep 2018 11:03:54 -0400 Subject: [PATCH 137/144] curses-win32: set class name on swell-created windows -- from fb57bbe2 --- WDL/win32_curses/curses_win32.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/WDL/win32_curses/curses_win32.cpp b/WDL/win32_curses/curses_win32.cpp index a918830d..953627fa 100644 --- a/WDL/win32_curses/curses_win32.cpp +++ b/WDL/win32_curses/curses_win32.cpp @@ -910,6 +910,7 @@ HWND curses_ControlCreator(HWND parent, const char *cname, int idx, const char * if (hw) { + SWELL_SetClassName(hw,WIN32CURSES_CLASS_NAME); SetWindowLong(hw,GWL_ID,idx); SetWindowPos(hw,HWND_TOP,x,y,w,h,SWP_NOZORDER|SWP_NOACTIVATE); ShowWindow(hw,SW_SHOWNA); From 23ddbbd0a1aacf933e48e656a70463ce77b1b934 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Thu, 27 Sep 2018 21:06:38 -0400 Subject: [PATCH 138/144] swell-dlggen patch for vc11+ from Gio -- from 1e6c0e41 --- WDL/swell/swell-dlggen.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/WDL/swell/swell-dlggen.h b/WDL/swell/swell-dlggen.h index 301777d1..5be30f78 100644 --- a/WDL/swell/swell-dlggen.h +++ b/WDL/swell/swell-dlggen.h @@ -163,8 +163,10 @@ struct SWELL_DlgResourceEntry #define WS_EX_RIGHT 0 #define SS_CENTERIMAGE 0 #define SS_NOPREFIX 0 - - + +// more ignore flags for vc11+ +#define LVS_ALIGNLEFT 0 /* 0x0800 */ + #ifndef IDC_STATIC #define IDC_STATIC 0 #endif From 1cbca983a9fff40ff5c6f8ec6fcaba24271569a6 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Sat, 29 Sep 2018 20:48:00 -0400 Subject: [PATCH 139/144] swell-generic: fix edit backspace behavior when removing end of lines [p=2040028] -- from 5390c948 --- WDL/swell/swell-wnd-generic.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/WDL/swell/swell-wnd-generic.cpp b/WDL/swell/swell-wnd-generic.cpp index 2e637435..7fc5b247 100644 --- a/WDL/swell/swell-wnd-generic.cpp +++ b/WDL/swell/swell-wnd-generic.cpp @@ -2298,7 +2298,11 @@ static LRESULT OnEditKeyDown(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, es->cursor_pos--; const char *buf = hwnd->m_title.Get(); int bytepos = WDL_utf8_charpos_to_bytepos(buf,es->cursor_pos); - if (bytepos > 0 && buf[bytepos] == '\n' && buf[bytepos-1] == '\r') hwnd->m_title.DeleteSub(bytepos-1, 2); + if (bytepos > 0 && buf[bytepos] == '\n' && buf[bytepos-1] == '\r') + { + hwnd->m_title.DeleteSub(bytepos-1, 2); + es->cursor_pos--; + } else hwnd->m_title.DeleteSub(bytepos, wdl_utf8_parsechar(hwnd->m_title.Get()+bytepos,NULL)); return 7; } From cf1804717ba1091606f9620294782b8213652f05 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Mon, 1 Oct 2018 09:36:26 -0400 Subject: [PATCH 140/144] swell-generic: keep menus on the same monitor as the source click/parent menu -- from 1018a827 --- WDL/swell/swell-menu-generic.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/WDL/swell/swell-menu-generic.cpp b/WDL/swell/swell-menu-generic.cpp index ffc8fa05..db614746 100644 --- a/WDL/swell/swell-menu-generic.cpp +++ b/WDL/swell/swell-menu-generic.cpp @@ -458,9 +458,9 @@ static LRESULT WINAPI submenuWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM wid+=lcol+rcol + (wid2?wid2+mcol:0); ReleaseDC(hwnd,hdc); - RECT tr={m_trackingPt.x,m_trackingPt.y, - m_trackingPt.x+wid+SWELL_UI_SCALE(4),m_trackingPt.y+ht+top_margin * 2}, vp; - SWELL_GetViewPort(&vp,&tr,true); + const RECT ref={m_trackingPt.x, m_trackingPt.y, m_trackingPt.x, m_trackingPt.y }; + RECT vp, tr={m_trackingPt.x,m_trackingPt.y, m_trackingPt.x+wid+SWELL_UI_SCALE(4),m_trackingPt.y+ht+top_margin * 2}; + SWELL_GetViewPort(&vp,&ref,true); vp.bottom -= 8; if (g_trackpopup_yroot.bottom > g_trackpopup_yroot.top && From 45414e987545b8eeb3fc02e95ce1c61fb1de399d Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 3 Oct 2018 12:50:07 -0400 Subject: [PATCH 141/144] coolscroll: fix linux hit test issue -- from a445b252 --- WDL/wingui/scrollbar/coolscroll.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/WDL/wingui/scrollbar/coolscroll.cpp b/WDL/wingui/scrollbar/coolscroll.cpp index 5f2b3c2a..1e4e0760 100644 --- a/WDL/wingui/scrollbar/coolscroll.cpp +++ b/WDL/wingui/scrollbar/coolscroll.cpp @@ -338,17 +338,18 @@ static BOOL IsScrollbarActive(SCROLLBAR *sb) return TRUE; } -#ifdef __APPLE__ +#ifndef _WIN32 static void GET_WINDOW_RECT(HWND hwnd, RECT *r) { GetWindowContentViewRect(hwnd,r); +#ifdef __APPLE__ if (r->top>r->bottom) { int tmp = r->top; r->top = r->bottom; r->bottom = tmp; } - +#endif } #else #define GET_WINDOW_RECT(hwnd, r) GetWindowRect(hwnd,r) From 03da8d78237de043ee5efdeb993fae5517299782 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 3 Oct 2018 13:04:49 -0400 Subject: [PATCH 142/144] Coolscroll: fix mouseover hit testing on macOS -- from eadbe137 --- WDL/wingui/scrollbar/coolscroll.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/WDL/wingui/scrollbar/coolscroll.cpp b/WDL/wingui/scrollbar/coolscroll.cpp index 1e4e0760..6192f6a4 100644 --- a/WDL/wingui/scrollbar/coolscroll.cpp +++ b/WDL/wingui/scrollbar/coolscroll.cpp @@ -3004,6 +3004,8 @@ static LRESULT CoolSB_Timer(SCROLLWND *swnd, HWND hwnd, WPARAM wTimerId, LPARAM //if the mouse moves outside the current scrollbar, //then kill the timer.. GetCursorPos(&pt); + POINT pt_orig = pt; + OSX_REMAP_SCREENY(hwnd,&pt.y); RECT mor = swnd->MouseOverRect; BOOL hasZoomButtons = swnd->MouseOverRect_hasZoomButtons; @@ -3019,7 +3021,7 @@ static LRESULT CoolSB_Timer(SCROLLWND *swnd, HWND hwnd, WPARAM wTimerId, LPARAM mor.right += extrasz; } - if(!PtInRect(&mor, pt)||WindowFromPoint(pt)!=hwnd) + if(!PtInRect(&mor, pt)||WindowFromPoint(pt_orig)!=hwnd) { KillTimer(hwnd, swnd->uMouseOverId); swnd->uMouseOverId = 0; From 9fc0668e519648fe97cf002b362fc0750f29ee07 Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 3 Oct 2018 13:49:43 -0400 Subject: [PATCH 143/144] coolscroll: fix some linux scrollbar flickering during drag -- from 08e72e2b --- WDL/wingui/scrollbar/coolscroll.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/WDL/wingui/scrollbar/coolscroll.cpp b/WDL/wingui/scrollbar/coolscroll.cpp index 6192f6a4..9c83c9cc 100644 --- a/WDL/wingui/scrollbar/coolscroll.cpp +++ b/WDL/wingui/scrollbar/coolscroll.cpp @@ -2368,6 +2368,9 @@ static LRESULT NCLButtonDown(SCROLLWND *sw, HWND hwnd, WPARAM wParam, LPARAM lPa } SetCapture(hwnd); +#ifndef _WIN32 + sw->uLastHitTestPortion = sw->uHitTestPortion = HTSCROLL_NONE; +#endif return 0; } From e942f3e0d511528e768a2a971238b96e2fa7b47e Mon Sep 17 00:00:00 2001 From: Cockos Inc Date: Wed, 3 Oct 2018 15:04:46 -0400 Subject: [PATCH 144/144] coolscroll: flush window drawing on macOS when updating scrollbar from mouseover -- from dc1e959e --- WDL/wingui/scrollbar/coolscroll.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/WDL/wingui/scrollbar/coolscroll.cpp b/WDL/wingui/scrollbar/coolscroll.cpp index 9c83c9cc..07aab188 100644 --- a/WDL/wingui/scrollbar/coolscroll.cpp +++ b/WDL/wingui/scrollbar/coolscroll.cpp @@ -338,6 +338,15 @@ static BOOL IsScrollbarActive(SCROLLBAR *sb) return TRUE; } +#ifdef __APPLE__ +static void ReleaseDCFlush(HWND hwnd, HDC hdc) +{ + ReleaseDC(hwnd,hdc); + SWELL_FlushWindow(hwnd); +} +#define ReleaseDC(hwnd,hdc) ReleaseDCFlush(hwnd,hdc) +#endif + #ifndef _WIN32 static void GET_WINDOW_RECT(HWND hwnd, RECT *r) {