experimental changes to get it compiling on win16

This commit is contained in:
IoIxD 2026-08-09 14:06:19 -07:00
commit 336019b94d
30 changed files with 8582 additions and 8442 deletions

3
.gitignore vendored
View file

@ -22,10 +22,11 @@ compile_flags.txt
/vms /vms
/BorMakefile /BorMakefile
*.err
*.pef *.pef
*.dsk *.dsk
*.bin *.bin
*.rsrc *.rsrc
*.finf *.finf
*.gdb *.gdb

27
WatMakefile generated
View file

@ -1,10 +1,22 @@
!ifndef %mw16
CC = wcc386 -bt=nt -q CC = wcc386 -bt=nt -q
!else
CC = wcc -bt=windows -q
!endif
LD = wlink option quiet LD = wlink option quiet
MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_TRUETYPE -dUSE_STB_IMAGE -dSTBI_NO_SIMD
MW_LDFLAGS = system nt_dll
EXE_CFLAGS = -i=include EXE_CFLAGS = -i=include
!ifndef %mw16
MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dUSE_STB_TRUETYPE -dUSE_STB_IMAGE -dSTBI_NO_SIMD -dMW_OPENGL
MW_LDFLAGS = system nt_dll
EXE_LDFLAGS = system nt EXE_LDFLAGS = system nt
!else
MW_CFLAGS = -bd -i=include -i=external/libz/include -d_MILSKO -d_MILSKO_BUILD -dUSE_GDI -dSTBI_NO_SIMD -dNO_IMAGE -os -oh
MW_LDFLAGS = system windows_dll
EXE_LDFLAGS = system windows
!endif
all: src/Mw.dll examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe all: src/Mw.dll examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe
lib: src/Mw.dll lib: src/Mw.dll
examples: examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe examples: examples/basic/box.exe examples/basic/calculator.exe examples/basic/checkbox.exe examples/basic/clipboard.exe examples/basic/colorpicker.exe examples/basic/combobox.exe examples/basic/example.exe examples/basic/filechooser.exe examples/basic/image.exe examples/basic/listbox.exe examples/basic/messagebox.exe examples/basic/periodic.exe examples/basic/progressbar.exe examples/basic/radiobox.exe examples/basic/rotate.exe examples/basic/scrollbar.exe examples/basic/sevensegment.exe examples/basic/subwindow.exe examples/basic/tab.exe examples/basic/treeview.exe examples/basic/viewport.exe examples/gldemos/boing.exe examples/gldemos/clock.exe examples/gldemos/cube.exe examples/gldemos/gears.exe examples/gldemos/triangle.exe examples/gldemos/tripaint.exe
@ -280,6 +292,7 @@ examples/basic/viewport.exe: examples/basic/viewport.obj src/Mw.dll
examples/basic/viewport.obj: examples/basic/viewport.c examples/basic/viewport.obj: examples/basic/viewport.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/viewport.c $(CC) $(EXE_CFLAGS) -fo=$@ examples/basic/viewport.c
!ifndef %mw16
examples/gldemos/boing.exe: examples/gldemos/boing.obj src/Mw.dll examples/gldemos/boing.exe: examples/gldemos/boing.obj src/Mw.dll
$(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/boing.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib $(LD) $(EXE_LDFLAGS) name $@ file examples/gldemos/boing.obj library clib3r.lib library src/Mw.lib library opengl32.lib library glu32.lib
@ -315,11 +328,15 @@ examples/gldemos/tripaint.exe: examples/gldemos/tripaint.obj src/Mw.dll
examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c examples/gldemos/tripaint.obj: examples/gldemos/tripaint.c
$(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/tripaint.c $(CC) $(EXE_CFLAGS) -fo=$@ examples/gldemos/tripaint.c
!endif
!ifndef %mw16
src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/stbtt.obj src/text/text.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj src/Mw.dll: external/libz/src/adler32.obj external/libz/src/compress.obj external/libz/src/crc32.obj external/libz/src/deflate.obj external/libz/src/gzclose.obj external/libz/src/gzlib.obj external/libz/src/gzread.obj external/libz/src/gzwrite.obj external/libz/src/infback.obj external/libz/src/inffast.obj external/libz/src/inflate.obj external/libz/src/inftrees.obj external/libz/src/trees.obj external/libz/src/uncompr.obj external/libz/src/zutil.obj external/stb_ds.obj external/stb_image.obj external/stb_truetype.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/cursor/arrow.obj src/cursor/cross.obj src/cursor/default.obj src/cursor/hidden.obj src/cursor/text.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/icon/back.obj src/icon/clock.obj src/icon/computer.obj src/icon/directory.obj src/icon/down.obj src/icon/error.obj src/icon/file.obj src/icon/forward.obj src/icon/info.obj src/icon/left.obj src/icon/news.obj src/icon/note.obj src/icon/right.obj src/icon/search.obj src/icon/up.obj src/icon/warning.obj src/lowlevel.obj src/string.obj src/text/font/boldfont.obj src/text/font/boldmonottf.obj src/text/font/boldttf.obj src/text/font/font.obj src/text/font/monottf.obj src/text/font/ttf.obj src/text/ft2.obj src/text/stbtt.obj src/text/text.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/opengl.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/stbtt.obj file src/text/text.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib library advapi32.lib $(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/libz/src/adler32.obj file external/libz/src/compress.obj file external/libz/src/crc32.obj file external/libz/src/deflate.obj file external/libz/src/gzclose.obj file external/libz/src/gzlib.obj file external/libz/src/gzread.obj file external/libz/src/gzwrite.obj file external/libz/src/infback.obj file external/libz/src/inffast.obj file external/libz/src/inflate.obj file external/libz/src/inftrees.obj file external/libz/src/trees.obj file external/libz/src/uncompr.obj file external/libz/src/zutil.obj file external/stb_ds.obj file external/stb_image.obj file external/stb_truetype.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/cursor/arrow.obj file src/cursor/cross.obj file src/cursor/default.obj file src/cursor/hidden.obj file src/cursor/text.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/icon/back.obj file src/icon/clock.obj file src/icon/computer.obj file src/icon/directory.obj file src/icon/down.obj file src/icon/error.obj file src/icon/file.obj file src/icon/forward.obj file src/icon/info.obj file src/icon/left.obj file src/icon/news.obj file src/icon/note.obj file src/icon/right.obj file src/icon/search.obj file src/icon/up.obj file src/icon/warning.obj file src/lowlevel.obj file src/string.obj file src/text/font/boldfont.obj file src/text/font/boldmonottf.obj file src/text/font/boldttf.obj file src/text/font/font.obj file src/text/font/monottf.obj file src/text/font/ttf.obj file src/text/ft2.obj file src/text/stbtt.obj file src/text/text.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/opengl.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clib3r.lib library opengl32.lib library gdi32.lib library user32.lib library advapi32.lib
!else
src/Mw.dll: external/stb_ds.obj src/abstract/charset.obj src/abstract/directory.obj src/abstract/dynamic.obj src/abstract/time.obj src/backend/gdi.obj src/color.obj src/core.obj src/default.obj src/dialog/colorpicker.obj src/dialog/directorychooser.obj src/dialog/filechooser.obj src/dialog/messagebox.obj src/draw.obj src/lowlevel.obj src/string.obj src/text/text.obj src/text/font/font.obj src/text/font/boldfont.obj src/unicode.obj src/widget/box.obj src/widget/button.obj src/widget/calendar.obj src/widget/checkbox.obj src/widget/combobox.obj src/widget/entry.obj src/widget/frame.obj src/widget/image.obj src/widget/label.obj src/widget/listbox.obj src/widget/menu.obj src/widget/numberentry.obj src/widget/progressbar.obj src/widget/radiobox.obj src/widget/scrollbar.obj src/widget/separator.obj src/widget/submenu.obj src/widget/subwindow.obj src/widget/tab.obj src/widget/table.obj src/widget/treeview.obj src/widget/viewport.obj src/widget/window.obj
$(LD) $(MW_LDFLAGS) option implib=src/Mw.lib name $@ file external/stb_ds.obj file src/abstract/charset.obj file src/abstract/directory.obj file src/abstract/dynamic.obj file src/abstract/time.obj file src/backend/gdi.obj file src/color.obj file src/core.obj file src/default.obj file src/dialog/colorpicker.obj file src/dialog/directorychooser.obj file src/dialog/filechooser.obj file src/dialog/messagebox.obj file src/draw.obj file src/lowlevel.obj file src/string.obj file src/text/text.obj file src/text/font/font.obj file src/text/font/boldfont.obj file src/unicode.obj file src/widget/box.obj file src/widget/button.obj file src/widget/calendar.obj file src/widget/checkbox.obj file src/widget/combobox.obj file src/widget/entry.obj file src/widget/frame.obj file src/widget/image.obj file src/widget/label.obj file src/widget/listbox.obj file src/widget/menu.obj file src/widget/numberentry.obj file src/widget/progressbar.obj file src/widget/radiobox.obj file src/widget/scrollbar.obj file src/widget/separator.obj file src/widget/submenu.obj file src/widget/subwindow.obj file src/widget/tab.obj file src/widget/table.obj file src/widget/treeview.obj file src/widget/viewport.obj file src/widget/window.obj library clibs.lib
!endif
external/libz/src/adler32.obj: external/libz/src/adler32.c external/libz/src/adler32.obj: external/libz/src/adler32.c
@ -474,8 +491,10 @@ src/widget/menu.obj: src/widget/menu.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/menu.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/menu.c
src/widget/numberentry.obj: src/widget/numberentry.c src/widget/numberentry.obj: src/widget/numberentry.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/numberentry.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/numberentry.c
!ifndef %mw16
src/widget/opengl.obj: src/widget/opengl.c src/widget/opengl.obj: src/widget/opengl.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/opengl.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/opengl.c
!endif
src/widget/progressbar.obj: src/widget/progressbar.c src/widget/progressbar.obj: src/widget/progressbar.c
$(CC) $(MW_CFLAGS) -fo=$@ src/widget/progressbar.c $(CC) $(MW_CFLAGS) -fo=$@ src/widget/progressbar.c
src/widget/radiobox.obj: src/widget/radiobox.c src/widget/radiobox.obj: src/widget/radiobox.c

View file

@ -2,8 +2,16 @@
MwWidget fpicker; MwWidget fpicker;
MwWidget window; MwWidget window;
MwWidget button;
/* This example does nothing on Win16 because we don't support the color picker on it (yet?) */
#ifdef __WINDOWS__
MwWidget missing_text;
#else
MwWidget button;
#endif
/* don't bother with color picker on win16 */
#ifndef __WINDOWS__
void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) { void MWAPI file_callback(MwWidget handle, void* user_data, void* call_data) {
char hexColor[8]; char hexColor[8];
MwRGB* rgb = call_data; MwRGB* rgb = call_data;
@ -29,6 +37,7 @@ void MWAPI file_picker(MwWidget handle, void* user_data, void* call_data) {
MwSetText(cpicker, MwNbackground, MwGetInteger(cpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground); MwSetText(cpicker, MwNbackground, MwGetInteger(cpicker, MwNdarkTheme) ? MwDefaultDarkBackground : MwDefaultBackground);
} }
#endif
int main() { int main() {
MwLibraryInit(); MwLibraryInit();
@ -37,12 +46,18 @@ int main() {
MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL); MwDEFAULT, 640, 480, MwNtitle, "color picker", NULL);
MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground); MwSetText(window, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
#ifndef __WINDOWS__
button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120, button = MwVaCreateWidget(MwButtonClass, "button", window, 160, 180, 320, 120,
MwNtext, "change window background", MwNtext, "change window background",
NULL); NULL);
MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground); MwSetText(button, MwNbackground, MwGetInteger(window, MwNdarkTheme) ? MwDefaultBackground : MwDefaultDarkBackground);
MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL); MwAddUserHandler(button, MwNactivateHandler, file_picker, NULL);
#else
missing_text = MwVaCreateWidget(MwLabelClass, NULL, window, 160, 180, 320, 120,
MwNtext, "Color picker doesn't yet exist on 16-bit Windows",
NULL);
#endif
MwLoop(window); MwLoop(window);
} }

241
external/stb_ds.h generated vendored
View file

@ -556,7 +556,8 @@ extern void * stbds_shmode_func(size_t elemsize, int mode);
#define stbds_arrins(a, i, v) (stbds_arrinsn((a), (i), 1), (a)[i] = (v)) #define stbds_arrins(a, i, v) (stbds_arrinsn((a), (i), 1), (a)[i] = (v))
#define stbds_arrmaybegrow(a, n) ((!(a) || stbds_header(a)->length + (n) > stbds_header(a)->capacity) \ #define stbds_arrmaybegrow(a, n) ((!(a) || stbds_header(a)->length + (n) > stbds_header(a)->capacity) \
? (stbds_arrgrow(a,n,0),0) : 0) ? (stbds_arrgrow(a, n, 0), 0) \
: 0)
#define stbds_arrgrow(a, b, c) ((a) = stbds_arrgrowf_wrapper((a), sizeof *(a), (b), (c))) #define stbds_arrgrow(a, b, c) ((a) = stbds_arrgrowf_wrapper((a), sizeof *(a), (b), (c)))
@ -662,14 +663,12 @@ typedef struct
ptrdiff_t temp; ptrdiff_t temp;
} stbds_array_header; } stbds_array_header;
typedef struct stbds_string_block typedef struct stbds_string_block {
{
struct stbds_string_block* next; struct stbds_string_block* next;
char storage[8]; char storage[8];
} stbds_string_block; } stbds_string_block;
struct stbds_string_arena struct stbds_string_arena {
{
stbds_string_block* storage; stbds_string_block* storage;
size_t remaining; size_t remaining;
unsigned char block; unsigned char block;
@ -679,8 +678,7 @@ struct stbds_string_arena
#define STBDS_HM_BINARY 0 #define STBDS_HM_BINARY 0
#define STBDS_HM_STRING 1 #define STBDS_HM_STRING 1
enum enum {
{
STBDS_SH_NONE, STBDS_SH_NONE,
STBDS_SH_DEFAULT, STBDS_SH_DEFAULT,
STBDS_SH_STRDUP, STBDS_SH_STRDUP,
@ -690,25 +688,32 @@ enum
#ifdef __cplusplus #ifdef __cplusplus
// in C we use implicit assignment from these void*-returning functions to T*. // in C we use implicit assignment from these void*-returning functions to T*.
// in C++ these templates make the same code work // in C++ these templates make the same code work
template<class T> static T * stbds_arrgrowf_wrapper(T *a, size_t elemsize, size_t addlen, size_t min_cap) { template <class T>
static T* stbds_arrgrowf_wrapper(T* a, size_t elemsize, size_t addlen, size_t min_cap) {
return (T*)stbds_arrgrowf((void*)a, elemsize, addlen, min_cap); return (T*)stbds_arrgrowf((void*)a, elemsize, addlen, min_cap);
} }
template<class T> static T * stbds_hmget_key_wrapper(T *a, size_t elemsize, void *key, size_t keysize, int mode) { template <class T>
static T* stbds_hmget_key_wrapper(T* a, size_t elemsize, void* key, size_t keysize, int mode) {
return (T*)stbds_hmget_key((void*)a, elemsize, key, keysize, mode); return (T*)stbds_hmget_key((void*)a, elemsize, key, keysize, mode);
} }
template<class T> static T * stbds_hmget_key_ts_wrapper(T *a, size_t elemsize, void *key, size_t keysize, ptrdiff_t *temp, int mode) { template <class T>
static T* stbds_hmget_key_ts_wrapper(T* a, size_t elemsize, void* key, size_t keysize, ptrdiff_t* temp, int mode) {
return (T*)stbds_hmget_key_ts((void*)a, elemsize, key, keysize, temp, mode); return (T*)stbds_hmget_key_ts((void*)a, elemsize, key, keysize, temp, mode);
} }
template<class T> static T * stbds_hmput_default_wrapper(T *a, size_t elemsize) { template <class T>
static T* stbds_hmput_default_wrapper(T* a, size_t elemsize) {
return (T*)stbds_hmput_default((void*)a, elemsize); return (T*)stbds_hmput_default((void*)a, elemsize);
} }
template<class T> static T * stbds_hmput_key_wrapper(T *a, size_t elemsize, void *key, size_t keysize, int mode) { template <class T>
static T* stbds_hmput_key_wrapper(T* a, size_t elemsize, void* key, size_t keysize, int mode) {
return (T*)stbds_hmput_key((void*)a, elemsize, key, keysize, mode); return (T*)stbds_hmput_key((void*)a, elemsize, key, keysize, mode);
} }
template<class T> static T * stbds_hmdel_key_wrapper(T *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode){ template <class T>
static T* stbds_hmdel_key_wrapper(T* a, size_t elemsize, void* key, size_t keysize, size_t keyoffset, int mode) {
return (T*)stbds_hmdel_key((void*)a, elemsize, key, keysize, keyoffset, mode); return (T*)stbds_hmdel_key((void*)a, elemsize, key, keysize, keyoffset, mode);
} }
template<class T> static T * stbds_shmode_func_wrapper(T *, size_t elemsize, int mode) { template <class T>
static T* stbds_shmode_func_wrapper(T*, size_t elemsize, int mode) {
return (T*)stbds_shmode_func(elemsize, mode); return (T*)stbds_shmode_func(elemsize, mode);
} }
#else #else
@ -723,7 +728,6 @@ template<class T> static T * stbds_shmode_func_wrapper(T *, size_t elemsize, int
#endif // INCLUDE_STB_DS_H #endif // INCLUDE_STB_DS_H
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// IMPLEMENTATION // IMPLEMENTATION
@ -759,8 +763,7 @@ size_t stbds_rehash_items;
// int *prev_allocs[65536]; // int *prev_allocs[65536];
// int num_prev; // int num_prev;
void *stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap) void* stbds_arrgrowf(void* a, size_t elemsize, size_t addlen, size_t min_cap) {
{
stbds_array_header temp = {0}; // force debugging stbds_array_header temp = {0}; // force debugging
void* b; void* b;
size_t min_len = stbds_arrlen(a) + addlen; size_t min_len = stbds_arrlen(a) + addlen;
@ -797,8 +800,7 @@ void *stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap)
return b; return b;
} }
void stbds_arrfreef(void *a) void stbds_arrfreef(void* a) {
{
STBDS_FREE(NULL, stbds_header(a)); STBDS_FREE(NULL, stbds_header(a));
} }
@ -848,8 +850,7 @@ typedef struct
static size_t stbds_hash_seed = 0x31415926; static size_t stbds_hash_seed = 0x31415926;
void stbds_rand_seed(size_t seed) void stbds_rand_seed(size_t seed) {
{
stbds_hash_seed = seed; stbds_hash_seed = seed;
} }
@ -860,8 +861,7 @@ void stbds_rand_seed(size_t seed)
#define STBDS_SIZE_T_BITS ((sizeof(size_t)) * 8) #define STBDS_SIZE_T_BITS ((sizeof(size_t)) * 8)
static size_t stbds_probe_position(size_t hash, size_t slot_count, size_t slot_log2) static size_t stbds_probe_position(size_t hash, size_t slot_count, size_t slot_log2) {
{
size_t pos; size_t pos;
STBDS_NOTUSED(slot_log2); STBDS_NOTUSED(slot_log2);
pos = hash & (slot_count - 1); pos = hash & (slot_count - 1);
@ -871,8 +871,7 @@ static size_t stbds_probe_position(size_t hash, size_t slot_count, size_t slot_l
return pos; return pos;
} }
static size_t stbds_log2(size_t slot_count) static size_t stbds_log2(size_t slot_count) {
{
size_t n = 0; size_t n = 0;
while(slot_count > 1) { while(slot_count > 1) {
slot_count >>= 1; slot_count >>= 1;
@ -881,8 +880,7 @@ static size_t stbds_log2(size_t slot_count)
return n; return n;
} }
static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_index *ot) static stbds_hash_index* stbds_make_hash_index(size_t slot_count, stbds_hash_index* ot) {
{
stbds_hash_index* t; stbds_hash_index* t;
t = (stbds_hash_index*)STBDS_REALLOC(NULL, 0, (slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE - 1); t = (stbds_hash_index*)STBDS_REALLOC(NULL, 0, (slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE - 1);
t->storage = (stbds_hash_bucket*)STBDS_ALIGN_FWD((size_t)(t + 1), STBDS_CACHE_LINE_SIZE); t->storage = (stbds_hash_bucket*)STBDS_ALIGN_FWD((size_t)(t + 1), STBDS_CACHE_LINE_SIZE);
@ -1001,8 +999,7 @@ static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_ind
pos &= (t->slot_count - 1); pos &= (t->slot_count - 1);
} }
} }
done: done:;
;
} }
} }
} }
@ -1013,8 +1010,7 @@ static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_ind
#define STBDS_ROTATE_LEFT(val, n) (((val) << (n)) | ((val) >> (STBDS_SIZE_T_BITS - (n)))) #define STBDS_ROTATE_LEFT(val, n) (((val) << (n)) | ((val) >> (STBDS_SIZE_T_BITS - (n))))
#define STBDS_ROTATE_RIGHT(val, n) (((val) >> (n)) | ((val) << (STBDS_SIZE_T_BITS - (n)))) #define STBDS_ROTATE_RIGHT(val, n) (((val) >> (n)) | ((val) << (STBDS_SIZE_T_BITS - (n))))
size_t stbds_hash_string(char *str, size_t seed) size_t stbds_hash_string(char* str, size_t seed) {
{
size_t hash = seed; size_t hash = seed;
while(*str) while(*str)
hash = STBDS_ROTATE_LEFT(hash, 9) + (unsigned char)*str++; hash = STBDS_ROTATE_LEFT(hash, 9) + (unsigned char)*str++;
@ -1048,8 +1044,7 @@ typedef int STBDS_SIPHASH_2_4_can_only_be_used_in_64_bit_builds[sizeof(size_t) =
#pragma warning(disable : 4127) // conditional expression is constant, for do..while(0) and sizeof()== #pragma warning(disable : 4127) // conditional expression is constant, for do..while(0) and sizeof()==
#endif #endif
static size_t stbds_siphash_bytes(void *p, size_t len, size_t seed) static size_t stbds_siphash_bytes(void* p, size_t len, size_t seed) {
{
unsigned char* d = (unsigned char*)p; unsigned char* d = (unsigned char*)p;
size_t i, j; size_t i, j;
size_t v0, v1, v2, v3, data; size_t v0, v1, v2, v3, data;
@ -1072,10 +1067,20 @@ static size_t stbds_siphash_bytes(void *p, size_t len, size_t seed)
#define STBDS_SIPROUND() \ #define STBDS_SIPROUND() \
do { \ do { \
v0 += v1; v1 = STBDS_ROTATE_LEFT(v1, 13); v1 ^= v0; v0 = STBDS_ROTATE_LEFT(v0,STBDS_SIZE_T_BITS/2); \ v0 += v1; \
v2 += v3; v3 = STBDS_ROTATE_LEFT(v3, 16); v3 ^= v2; \ v1 = STBDS_ROTATE_LEFT(v1, 13); \
v2 += v1; v1 = STBDS_ROTATE_LEFT(v1, 17); v1 ^= v2; v2 = STBDS_ROTATE_LEFT(v2,STBDS_SIZE_T_BITS/2); \ v1 ^= v0; \
v0 += v3; v3 = STBDS_ROTATE_LEFT(v3, 21); v3 ^= v0; \ v0 = STBDS_ROTATE_LEFT(v0, STBDS_SIZE_T_BITS / 2); \
v2 += v3; \
v3 = STBDS_ROTATE_LEFT(v3, 16); \
v3 ^= v2; \
v2 += v1; \
v1 = STBDS_ROTATE_LEFT(v1, 17); \
v1 ^= v2; \
v2 = STBDS_ROTATE_LEFT(v2, STBDS_SIZE_T_BITS / 2); \
v0 += v3; \
v3 = STBDS_ROTATE_LEFT(v3, 21); \
v3 ^= v0; \
} while(0) } while(0)
for(i = 0; i + sizeof(size_t) <= len; i += sizeof(size_t), d += sizeof(size_t)) { for(i = 0; i + sizeof(size_t) <= len; i += sizeof(size_t), d += sizeof(size_t)) {
@ -1089,14 +1094,22 @@ static size_t stbds_siphash_bytes(void *p, size_t len, size_t seed)
} }
data = len << (STBDS_SIZE_T_BITS - 8); data = len << (STBDS_SIZE_T_BITS - 8);
switch(len - i) { switch(len - i) {
case 7: data |= ((size_t) d[6] << 24) << 24; // fall through case 7:
case 6: data |= ((size_t) d[5] << 20) << 20; // fall through data |= ((size_t)d[6] << 24) << 24; // fall through
case 5: data |= ((size_t) d[4] << 16) << 16; // fall through case 6:
case 4: data |= (d[3] << 24); // fall through data |= ((size_t)d[5] << 20) << 20; // fall through
case 3: data |= (d[2] << 16); // fall through case 5:
case 2: data |= (d[1] << 8); // fall through data |= ((size_t)d[4] << 16) << 16; // fall through
case 1: data |= d[0]; // fall through case 4:
case 0: break; data |= (d[3] << 24); // fall through
case 3:
data |= (d[2] << 16); // fall through
case 2:
data |= (d[1] << 8); // fall through
case 1:
data |= d[0]; // fall through
case 0:
break;
} }
v3 ^= data; v3 ^= data;
for(j = 0; j < STBDS_SIPHASH_C_ROUNDS; ++j) for(j = 0; j < STBDS_SIPHASH_C_ROUNDS; ++j)
@ -1113,8 +1126,7 @@ static size_t stbds_siphash_bytes(void *p, size_t len, size_t seed)
#endif #endif
} }
size_t stbds_hash_bytes(void *p, size_t len, size_t seed) size_t stbds_hash_bytes(void* p, size_t len, size_t seed) {
{
#ifdef STBDS_SIPHASH_2_4 #ifdef STBDS_SIPHASH_2_4
return stbds_siphash_bytes(p, len, seed); return stbds_siphash_bytes(p, len, seed);
#else #else
@ -1199,9 +1211,7 @@ size_t stbds_hash_bytes(void *p, size_t len, size_t seed)
#pragma warning(pop) #pragma warning(pop)
#endif #endif
static int stbds_is_key_equal(void* a, size_t elemsize, void* key, size_t keysize, size_t keyoffset, int mode, size_t i) {
static int stbds_is_key_equal(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode, size_t i)
{
if(mode >= STBDS_HM_STRING) if(mode >= STBDS_HM_STRING)
return 0 == strcmp((char*)key, *(char**)((char*)a + elemsize * i + keyoffset)); return 0 == strcmp((char*)key, *(char**)((char*)a + elemsize * i + keyoffset));
else else
@ -1213,8 +1223,7 @@ static int stbds_is_key_equal(void *a, size_t elemsize, void *key, size_t keysiz
#define stbds_hash_table(a) ((stbds_hash_index*)stbds_header(a)->hash_table) #define stbds_hash_table(a) ((stbds_hash_index*)stbds_header(a)->hash_table)
void stbds_hmfree_func(void *a, size_t elemsize) void stbds_hmfree_func(void* a, size_t elemsize) {
{
if(a == NULL) return; if(a == NULL) return;
if(stbds_hash_table(a) != NULL) { if(stbds_hash_table(a) != NULL) {
if(stbds_hash_table(a)->string.mode == STBDS_SH_STRDUP) { if(stbds_hash_table(a)->string.mode == STBDS_SH_STRDUP) {
@ -1229,8 +1238,7 @@ void stbds_hmfree_func(void *a, size_t elemsize)
STBDS_FREE(NULL, stbds_header(a)); STBDS_FREE(NULL, stbds_header(a));
} }
static ptrdiff_t stbds_hm_find_slot(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode) static ptrdiff_t stbds_hm_find_slot(void* a, size_t elemsize, void* key, size_t keysize, size_t keyoffset, int mode) {
{
void* raw_a = STBDS_HASH_TO_ARR(a, elemsize); void* raw_a = STBDS_HASH_TO_ARR(a, elemsize);
stbds_hash_index* table = stbds_hash_table(raw_a); stbds_hash_index* table = stbds_hash_table(raw_a);
size_t hash = mode >= STBDS_HM_STRING ? stbds_hash_string((char*)key, table->seed) : stbds_hash_bytes(key, keysize, table->seed); size_t hash = mode >= STBDS_HM_STRING ? stbds_hash_string((char*)key, table->seed) : stbds_hash_bytes(key, keysize, table->seed);
@ -1278,8 +1286,7 @@ static ptrdiff_t stbds_hm_find_slot(void *a, size_t elemsize, void *key, size_t
/* NOTREACHED */ /* NOTREACHED */
} }
void * stbds_hmget_key_ts(void *a, size_t elemsize, void *key, size_t keysize, ptrdiff_t *temp, int mode) void* stbds_hmget_key_ts(void* a, size_t elemsize, void* key, size_t keysize, ptrdiff_t* temp, int mode) {
{
size_t keyoffset = 0; size_t keyoffset = 0;
if(a == NULL) { if(a == NULL) {
// make it non-empty so we can return a temp // make it non-empty so we can return a temp
@ -1309,16 +1316,14 @@ void * stbds_hmget_key_ts(void *a, size_t elemsize, void *key, size_t keysize, p
} }
} }
void * stbds_hmget_key(void *a, size_t elemsize, void *key, size_t keysize, int mode) void* stbds_hmget_key(void* a, size_t elemsize, void* key, size_t keysize, int mode) {
{
ptrdiff_t temp; ptrdiff_t temp;
void* p = stbds_hmget_key_ts(a, elemsize, key, keysize, &temp, mode); void* p = stbds_hmget_key_ts(a, elemsize, key, keysize, &temp, mode);
stbds_temp(STBDS_HASH_TO_ARR(p, elemsize)) = temp; stbds_temp(STBDS_HASH_TO_ARR(p, elemsize)) = temp;
return p; return p;
} }
void * stbds_hmput_default(void *a, size_t elemsize) void* stbds_hmput_default(void* a, size_t elemsize) {
{
// three cases: // three cases:
// a is NULL <- allocate // a is NULL <- allocate
// a has a hash table but no entries, because of shmode <- grow // a has a hash table but no entries, because of shmode <- grow
@ -1334,8 +1339,7 @@ void * stbds_hmput_default(void *a, size_t elemsize)
static char* stbds_strdup(char* str); static char* stbds_strdup(char* str);
void *stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int mode) void* stbds_hmput_key(void* a, size_t elemsize, void* key, size_t keysize, int mode) {
{
size_t keyoffset = 0; size_t keyoffset = 0;
void* raw_a; void* raw_a;
stbds_hash_index* table; stbds_hash_index* table;
@ -1448,18 +1452,25 @@ void *stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int m
stbds_temp(a) = i - 1; stbds_temp(a) = i - 1;
switch(table->string.mode) { switch(table->string.mode) {
case STBDS_SH_STRDUP: stbds_temp_key(a) = *(char **) ((char *) a + elemsize*i) = stbds_strdup((char*) key); break; case STBDS_SH_STRDUP:
case STBDS_SH_ARENA: stbds_temp_key(a) = *(char **) ((char *) a + elemsize*i) = stbds_stralloc(&table->string, (char*)key); break; stbds_temp_key(a) = *(char**)((char*)a + elemsize * i) = stbds_strdup((char*)key);
case STBDS_SH_DEFAULT: stbds_temp_key(a) = *(char **) ((char *) a + elemsize*i) = (char *) key; break; break;
default: memcpy((char *) a + elemsize*i, key, keysize); break; case STBDS_SH_ARENA:
stbds_temp_key(a) = *(char**)((char*)a + elemsize * i) = stbds_stralloc(&table->string, (char*)key);
break;
case STBDS_SH_DEFAULT:
stbds_temp_key(a) = *(char**)((char*)a + elemsize * i) = (char*)key;
break;
default:
memcpy((char*)a + elemsize * i, key, keysize);
break;
} }
} }
return STBDS_ARR_TO_HASH(a, elemsize); return STBDS_ARR_TO_HASH(a, elemsize);
} }
} }
void * stbds_shmode_func(size_t elemsize, int mode) void* stbds_shmode_func(size_t elemsize, int mode) {
{
void* a = stbds_arrgrowf(0, elemsize, 0, 1); void* a = stbds_arrgrowf(0, elemsize, 0, 1);
stbds_hash_index* h; stbds_hash_index* h;
memset(a, 0, elemsize); memset(a, 0, elemsize);
@ -1469,8 +1480,7 @@ void * stbds_shmode_func(size_t elemsize, int mode)
return STBDS_ARR_TO_HASH(a, elemsize); return STBDS_ARR_TO_HASH(a, elemsize);
} }
void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode) void* stbds_hmdel_key(void* a, size_t elemsize, void* key, size_t keysize, size_t keyoffset, int mode) {
{
if(a == NULL) { if(a == NULL) {
return 0; return 0;
} else { } else {
@ -1537,8 +1547,7 @@ void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size
/* NOTREACHED */ /* NOTREACHED */
} }
static char *stbds_strdup(char *str) static char* stbds_strdup(char* str) {
{
// to keep replaceable allocator simple, we don't want to use strdup. // to keep replaceable allocator simple, we don't want to use strdup.
// rolling our own also avoids problem of strdup vs _strdup // rolling our own also avoids problem of strdup vs _strdup
size_t len = strlen(str) + 1; size_t len = strlen(str) + 1;
@ -1554,8 +1563,7 @@ static char *stbds_strdup(char *str)
#define STBDS_STRING_ARENA_BLOCKSIZE_MAX (1u << 20) #define STBDS_STRING_ARENA_BLOCKSIZE_MAX (1u << 20)
#endif #endif
char *stbds_stralloc(stbds_string_arena *a, char *str) char* stbds_stralloc(stbds_string_arena* a, char* str) {
{
char* p; char* p;
size_t len = strlen(str) + 1; size_t len = strlen(str) + 1;
if(len > a->remaining) { if(len > a->remaining) {
@ -1602,8 +1610,7 @@ char *stbds_stralloc(stbds_string_arena *a, char *str)
return p; return p;
} }
void stbds_strreset(stbds_string_arena *a) void stbds_strreset(stbds_string_arena* a) {
{
stbds_string_block *x, *y; stbds_string_block *x, *y;
x = a->storage; x = a->storage;
while(x) { while(x) {
@ -1631,13 +1638,16 @@ void stbds_strreset(stbds_string_arena *a)
#include <assert.h> #include <assert.h>
#endif #endif
typedef struct { int key,b,c,d; } stbds_struct; typedef struct {
typedef struct { int key[2],b,c,d; } stbds_struct2; int key, b, c, d;
} stbds_struct;
typedef struct {
int key[2], b, c, d;
} stbds_struct2;
static char buffer[256]; static char buffer[256];
char *strkey(int n) char* strkey(int n) {
{ #if defined(_WIN32) || defined(__WINDOWS__) && defined(__STDC_WANT_SECURE_LIB__)
#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__)
sprintf_s(buffer, sizeof(buffer), "test_%d", n); sprintf_s(buffer, sizeof(buffer), "test_%d", n);
#else #else
sprintf(buffer, "test_%d", n); sprintf(buffer, "test_%d", n);
@ -1645,8 +1655,7 @@ char *strkey(int n)
return buffer; return buffer;
} }
void stbds_unit_tests(void) void stbds_unit_tests(void) {
{
#if defined(_MSC_VER) && _MSC_VER <= 1200 && defined(__cplusplus) #if defined(_MSC_VER) && _MSC_VER <= 1200 && defined(__cplusplus)
// VC6 C++ doesn't like the template<> trick on unnamed structures, so do nothing! // VC6 C++ doesn't like the template<> trick on unnamed structures, so do nothing!
STBDS_ASSERT(0); STBDS_ASSERT(0);
@ -1654,9 +1663,18 @@ void stbds_unit_tests(void)
const int testsize = 100000; const int testsize = 100000;
const int testsize2 = testsize / 20; const int testsize2 = testsize / 20;
int* arr = NULL; int* arr = NULL;
struct { int key; int value; } *intmap = NULL; struct {
struct { char *key; int value; } *strmap = NULL, s; int key;
struct { stbds_struct key; int value; } *map = NULL; int value;
}* intmap = NULL;
struct {
char* key;
int value;
} *strmap = NULL, s;
struct {
stbds_struct key;
int value;
}* map = NULL;
stbds_struct* map2 = NULL; stbds_struct* map2 = NULL;
stbds_struct2* map3 = NULL; stbds_struct2* map3 = NULL;
stbds_string_arena sa = {0}; stbds_string_arena sa = {0};
@ -1673,16 +1691,25 @@ void stbds_unit_tests(void)
} }
for(i = 0; i < 4; ++i) { for(i = 0; i < 4; ++i) {
arrpush(arr,1); arrpush(arr,2); arrpush(arr,3); arrpush(arr,4); arrpush(arr, 1);
arrpush(arr, 2);
arrpush(arr, 3);
arrpush(arr, 4);
arrdel(arr, i); arrdel(arr, i);
arrfree(arr); arrfree(arr);
arrpush(arr,1); arrpush(arr,2); arrpush(arr,3); arrpush(arr,4); arrpush(arr, 1);
arrpush(arr, 2);
arrpush(arr, 3);
arrpush(arr, 4);
arrdelswap(arr, i); arrdelswap(arr, i);
arrfree(arr); arrfree(arr);
} }
for(i = 0; i < 5; ++i) { for(i = 0; i < 5; ++i) {
arrpush(arr,1); arrpush(arr,2); arrpush(arr,3); arrpush(arr,4); arrpush(arr, 1);
arrpush(arr, 2);
arrpush(arr, 3);
arrpush(arr, 4);
stbds_arrins(arr, i, 5); stbds_arrins(arr, i, 5);
STBDS_ASSERT(arr[i] == 5); STBDS_ASSERT(arr[i] == 5);
if(i < 4) if(i < 4)
@ -1699,20 +1726,24 @@ void stbds_unit_tests(void)
hmput(intmap, i, i * 5); hmput(intmap, i, i * 5);
for(i = 0; i < testsize; i += 1) { for(i = 0; i < testsize; i += 1) {
if(i & 1) STBDS_ASSERT(hmget(intmap, i) == -2); if(i & 1) STBDS_ASSERT(hmget(intmap, i) == -2);
else STBDS_ASSERT(hmget(intmap, i) == i*5); else
STBDS_ASSERT(hmget(intmap, i) == i * 5);
if(i & 1) STBDS_ASSERT(hmget_ts(intmap, i, temp) == -2); if(i & 1) STBDS_ASSERT(hmget_ts(intmap, i, temp) == -2);
else STBDS_ASSERT(hmget_ts(intmap, i, temp) == i*5); else
STBDS_ASSERT(hmget_ts(intmap, i, temp) == i * 5);
} }
for(i = 0; i < testsize; i += 2) for(i = 0; i < testsize; i += 2)
hmput(intmap, i, i * 3); hmput(intmap, i, i * 3);
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
if(i & 1) STBDS_ASSERT(hmget(intmap, i) == -2); if(i & 1) STBDS_ASSERT(hmget(intmap, i) == -2);
else STBDS_ASSERT(hmget(intmap, i) == i*3); else
STBDS_ASSERT(hmget(intmap, i) == i * 3);
for(i = 2; i < testsize; i += 4) for(i = 2; i < testsize; i += 4)
hmdel(intmap, i); // delete half the entries hmdel(intmap, i); // delete half the entries
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
if(i & 3) STBDS_ASSERT(hmget(intmap, i) == -2); if(i & 3) STBDS_ASSERT(hmget(intmap, i) == -2);
else STBDS_ASSERT(hmget(intmap, i) == i*3); else
STBDS_ASSERT(hmget(intmap, i) == i * 3);
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
hmdel(intmap, i); // delete the rest of the entries hmdel(intmap, i); // delete the rest of the entries
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
@ -1780,12 +1811,14 @@ void stbds_unit_tests(void)
shput(strmap, strkey(i), i * 3); shput(strmap, strkey(i), i * 3);
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
if(i & 1) STBDS_ASSERT(shget(strmap, strkey(i)) == -2); if(i & 1) STBDS_ASSERT(shget(strmap, strkey(i)) == -2);
else STBDS_ASSERT(shget(strmap, strkey(i)) == i*3); else
STBDS_ASSERT(shget(strmap, strkey(i)) == i * 3);
for(i = 2; i < testsize; i += 4) for(i = 2; i < testsize; i += 4)
shdel(strmap, strkey(i)); // delete half the entries shdel(strmap, strkey(i)); // delete half the entries
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
if(i & 3) STBDS_ASSERT(shget(strmap, strkey(i)) == -2); if(i & 3) STBDS_ASSERT(shget(strmap, strkey(i)) == -2);
else STBDS_ASSERT(shget(strmap, strkey(i)) == i*3); else
STBDS_ASSERT(shget(strmap, strkey(i)) == i * 3);
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
shdel(strmap, strkey(i)); // delete the rest of the entries shdel(strmap, strkey(i)); // delete the rest of the entries
for(i = 0; i < testsize; i += 1) for(i = 0; i < testsize; i += 1)
@ -1794,7 +1827,10 @@ void stbds_unit_tests(void)
} }
{ {
struct { char *key; char value; } *hash = NULL; struct {
char* key;
char value;
}* hash = NULL;
char name[4] = "jen"; char name[4] = "jen";
shput(hash, "bob", 'h'); shput(hash, "bob", 'h');
shput(hash, "sally", 'e'); shput(hash, "sally", 'e');
@ -1815,9 +1851,11 @@ void stbds_unit_tests(void)
stbds_struct s = {i, i * 2, i * 3, i * 4}; stbds_struct s = {i, i * 2, i * 3, i * 4};
stbds_struct t = {i, i * 2, i * 3 + 1, i * 4}; stbds_struct t = {i, i * 2, i * 3 + 1, i * 4};
if(i & 1) STBDS_ASSERT(hmget(map, s) == 0); if(i & 1) STBDS_ASSERT(hmget(map, s) == 0);
else STBDS_ASSERT(hmget(map, s) == i*5); else
STBDS_ASSERT(hmget(map, s) == i * 5);
if(i & 1) STBDS_ASSERT(hmget_ts(map, s, temp) == 0); if(i & 1) STBDS_ASSERT(hmget_ts(map, s, temp) == 0);
else STBDS_ASSERT(hmget_ts(map, s, temp) == i*5); else
STBDS_ASSERT(hmget_ts(map, s, temp) == i * 5);
// STBDS_ASSERT(hmget(map, t.key) == 0); // STBDS_ASSERT(hmget(map, t.key) == 0);
} }
@ -1831,7 +1869,8 @@ void stbds_unit_tests(void)
stbds_struct s = {i, i * 2, i * 3, i * 4}; stbds_struct s = {i, i * 2, i * 3, i * 4};
stbds_struct t = {i, i * 2, i * 3 + 1, i * 4}; stbds_struct t = {i, i * 2, i * 3 + 1, i * 4};
if(i & 1) STBDS_ASSERT(hmgets(map2, s.key).d == 0); if(i & 1) STBDS_ASSERT(hmgets(map2, s.key).d == 0);
else STBDS_ASSERT(hmgets(map2, s.key).d == i*4); else
STBDS_ASSERT(hmgets(map2, s.key).d == i * 4);
// STBDS_ASSERT(hmgetp(map2, t.key) == 0); // STBDS_ASSERT(hmgetp(map2, t.key) == 0);
} }
hmfree(map2); hmfree(map2);
@ -1844,14 +1883,14 @@ void stbds_unit_tests(void)
stbds_struct2 s = {{i, i * 2}, i * 3, i * 4, i * 5}; stbds_struct2 s = {{i, i * 2}, i * 3, i * 4, i * 5};
stbds_struct2 t = {{i, i * 2}, i * 3 + 1, i * 4, i * 5}; stbds_struct2 t = {{i, i * 2}, i * 3 + 1, i * 4, i * 5};
if(i & 1) STBDS_ASSERT(hmgets(map3, s.key).d == 0); if(i & 1) STBDS_ASSERT(hmgets(map3, s.key).d == 0);
else STBDS_ASSERT(hmgets(map3, s.key).d == i*5); else
STBDS_ASSERT(hmgets(map3, s.key).d == i * 5);
// STBDS_ASSERT(hmgetp(map3, t.key) == 0); // STBDS_ASSERT(hmgetp(map3, t.key) == 0);
} }
#endif #endif
} }
#endif #endif
/* /*
------------------------------------------------------------------------------ ------------------------------------------------------------------------------
This software is available under 2 licenses -- choose whichever you prefer. This software is available under 2 licenses -- choose whichever you prefer.

1359
external/stb_image.h generated vendored

File diff suppressed because it is too large Load diff

View file

@ -49,6 +49,9 @@ typedef __int8 MwI8;
typedef unsigned __int8 MwU8; typedef unsigned __int8 MwU8;
#define MW_OTHER_TYPES_DEFINED #define MW_OTHER_TYPES_DEFINED
#elif defined(__WINDOWS__)
typedef long long MwI64;
typedef unsigned long long MwU64;
#else #else
/* out of hope */ /* out of hope */
typedef long MwI64; typedef long MwI64;
@ -58,6 +61,16 @@ typedef unsigned long MwU64;
#ifdef MW_OTHER_TYPES_DEFINED #ifdef MW_OTHER_TYPES_DEFINED
#undef MW_OTHER_TYPES_DEFINED #undef MW_OTHER_TYPES_DEFINED
#else #else
#ifdef __WINDOWS__
typedef long MwI32;
typedef unsigned long MwU32;
typedef int MwI16;
typedef unsigned int MwU16;
typedef signed char MwI8;
typedef unsigned char MwU8;
#else
typedef int MwI32; typedef int MwI32;
typedef unsigned int MwU32; typedef unsigned int MwU32;
@ -67,6 +80,7 @@ typedef unsigned short MwU16;
typedef signed char MwI8; typedef signed char MwI8;
typedef unsigned char MwU8; typedef unsigned char MwU8;
#endif #endif
#endif
typedef MwI64 MwOffset; typedef MwI64 MwOffset;

View file

@ -35,7 +35,11 @@ enum MwALIGNMENT {
/*! /*!
* @brief Default * @brief Default
*/ */
#ifdef __WINDOWS__
#define MwDEFAULT 0x0ffff
#else
#define MwDEFAULT 0x0fffffff #define MwDEFAULT 0x0fffffff
#endif
/*! /*!
* @brief Directory entry type * @brief Directory entry type

View file

@ -12,6 +12,9 @@
extern "C" { extern "C" {
#endif #endif
#ifdef __WINDOWS__
#error Color Picker Widget is not avaliable on Win16
#else
/*! /*!
* @brief Creates a color picker * @brief Creates a color picker
* @param handle Widget * @param handle Widget
@ -19,6 +22,7 @@ extern "C" {
* @return Widget * @return Widget
*/ */
MWDECL MwWidget MWAPI MwColorPicker(MwWidget handle, const char* title); MWDECL MwWidget MWAPI MwColorPicker(MwWidget handle, const char* title);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -162,6 +162,7 @@ MWDECL unsigned char* MWAPI MwPixmapGetRaw(MwLLPixmap pixmap);
*/ */
MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect); MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect);
#ifndef __WINDOWS__
/*! /*!
* @brief Creates a pixmap from XPM data * @brief Creates a pixmap from XPM data
* @param handle Widget * @param handle Widget
@ -169,6 +170,7 @@ MWDECL void MWAPI MwPixmapGetSize(MwLLPixmap pixmap, MwRect* rect);
* @return Pixmap * @return Pixmap
*/ */
MWDECL MwLLPixmap MWAPI MwLoadXPM(MwWidget handle, char** data); MWDECL MwLLPixmap MWAPI MwLoadXPM(MwWidget handle, char** data);
#endif
/*! /*!
* @brief Creates a pixmap from icon data * @brief Creates a pixmap from icon data

View file

@ -334,6 +334,7 @@ MWDECL void (*MwLLRaise)(MwLL handle);
MWDECL void (*MwLLClip)(MwLL handle, MwRect* rect); MWDECL void (*MwLLClip)(MwLL handle, MwRect* rect);
/* font renderer */ /* font renderer */
#ifndef __WINDOWS__
MWDECL void MwFLSetup(void); MWDECL void MwFLSetup(void);
#ifdef USE_FREETYPE2 #ifdef USE_FREETYPE2
@ -348,6 +349,7 @@ MWDECL int (*MwFLTextWidth)(MwFLFont ttf, const char* text);
MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count); MWDECL int (*MwFLTextHeight)(MwFLFont ttf, int count);
MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px); MWDECL void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px);
MWDECL void (*MwFLFontFree)(void* handle); MWDECL void (*MwFLFontFree)(void* handle);
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -42,6 +42,7 @@ struct _MwLLGDIPixmap {
RGBQUAD* quad; RGBQUAD* quad;
HBITMAP hBitmap; HBITMAP hBitmap;
HDC hBitmapMem;
HBITMAP hMask; HBITMAP hMask;
HBITMAP hMask2; HBITMAP hMask2;
}; };

View file

@ -20,11 +20,18 @@
#include <wchar.h> #include <wchar.h>
#define MW_HAS_WCHAR #define MW_HAS_WCHAR
#endif #endif
#ifdef _WIN32 #if defined(_WIN32) || defined(__WINDOWS__)
#include <direct.h> #include <direct.h>
#ifdef _MILSKO #ifdef _MILSKO
#include <windows.h> #include <windows.h>
#if defined(__WINDOWS__)
#include <dos.h>
#define GetSysColorBrush(x) CreateSolidBrush(GetSysColor(x))
#endif
#ifndef HALFTONE
#define HALFTONE 4
#endif
#ifndef GWLP_USERDATA #ifndef GWLP_USERDATA
#define GWLP_USERDATA GWL_USERDATA #define GWLP_USERDATA GWL_USERDATA
#define GWLP_WNDPROC GWL_WNDPROC #define GWLP_WNDPROC GWL_WNDPROC
@ -35,6 +42,9 @@
#define SetClassLongPtr SetClassLong #define SetClassLongPtr SetClassLong
#define GetClassLongPtr GetClassLong #define GetClassLongPtr GetClassLong
#endif #endif
#ifndef GWL_USERDATA
#define GWL_USERDATA (-21)
#endif
#ifndef WM_MOUSEWHEEL #ifndef WM_MOUSEWHEEL
#define WM_MOUSEWHEEL 0x020a #define WM_MOUSEWHEEL 0x020a
#define GET_WHEEL_DELTA_WPARAM(x) ((short)HIWORD(x)) #define GET_WHEEL_DELTA_WPARAM(x) ((short)HIWORD(x))
@ -89,9 +99,9 @@
#endif #endif
/* Windows */ /* Windows */
#if defined(_MILSKO) && defined(_MILSKO_BUILD) && defined(_WIN32) #if defined(_MILSKO) && defined(_MILSKO_BUILD) && defined(_WIN32) || defined(__WINDOWS__)
#define MWDECL extern __declspec(dllexport) #define MWDECL extern __declspec(dllexport)
#elif defined(_WIN32) #elif defined(_WIN32) || defined(__WINDOWS__)
#define MWDECL extern __declspec(dllimport) #define MWDECL extern __declspec(dllimport)
/* GCC/Clang */ /* GCC/Clang */
/* First check if we have __has_attribute and can check for the existence of visibility */ /* First check if we have __has_attribute and can check for the existence of visibility */
@ -111,7 +121,7 @@
#define MWDECL extern #define MWDECL extern
#endif #endif
#if defined(_WIN32) #if defined(_WIN32) || defined(__WINDOWS__)
#define MWAPI __cdecl #define MWAPI __cdecl
#else #else
#define MWAPI #define MWAPI

View file

@ -23,14 +23,18 @@
#include <Mw/Abstract/Time.h> #include <Mw/Abstract/Time.h>
#include <Mw/Abstract/CharSet.h> #include <Mw/Abstract/CharSet.h>
#ifndef __WINDOWS__
#include <Mw/Resource/Icon.h> #include <Mw/Resource/Icon.h>
#endif
#include <Mw/Resource/Cursor.h> #include <Mw/Resource/Cursor.h>
#include <Mw/Resource/Font.h> #include <Mw/Resource/Font.h>
#include <Mw/Dialog/MessageBox.h> #include <Mw/Dialog/MessageBox.h>
#include <Mw/Dialog/FileChooser.h> #include <Mw/Dialog/FileChooser.h>
#include <Mw/Dialog/DirectoryChooser.h> #include <Mw/Dialog/DirectoryChooser.h>
#ifndef __WINDOWS__
#include <Mw/Dialog/ColorPicker.h> #include <Mw/Dialog/ColorPicker.h>
#endif
#include <Mw/Widget/Box.h> #include <Mw/Widget/Box.h>
#include <Mw/Widget/Button.h> #include <Mw/Widget/Button.h>

View file

@ -13,6 +13,7 @@
extern "C" { extern "C" {
#endif #endif
#ifndef __WINDOWS__
/*! /*!
* @brief Default cursor * @brief Default cursor
*/ */
@ -63,6 +64,8 @@ MWDECL MwCursor MwCursorHidden;
*/ */
MWDECL MwCursor MwCursorHiddenMask; MWDECL MwCursor MwCursorHiddenMask;
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View file

@ -10,7 +10,7 @@
#include <Mw/TypeDefs.h> #include <Mw/TypeDefs.h>
#if !defined(MW_OPENGL_NO_INCLUDE) && !defined(__gl_h_) #if !defined(MW_OPENGL_NO_INCLUDE) && !defined(__gl_h_)
#ifdef _WIN32 #if defined(_WIN32) || defined(__WINDOWS__)
#include <windows.h> #include <windows.h>
#elif defined(__APPLE__) #elif defined(__APPLE__)
#else #else

View file

@ -1,11 +1,16 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#ifdef _WIN32 #if defined(_WIN32)
typedef struct dir { typedef struct dir {
HANDLE hFind; HANDLE hFind;
WIN32_FIND_DATA ffd; WIN32_FIND_DATA ffd;
int next; int next;
} dir_t; } dir_t;
#elif defined(__WINDOWS__)
typedef struct dir {
struct find_t result;
int next;
} dir_t;
#elif defined(CLASSIC_MAC_OS) #elif defined(CLASSIC_MAC_OS)
typedef struct dir { typedef struct dir {
int dummy; int dummy;
@ -19,7 +24,7 @@ typedef struct dir {
void* MwDirectoryOpen(const char* path) { void* MwDirectoryOpen(const char* path) {
dir_t* dir = malloc(sizeof(*dir)); dir_t* dir = malloc(sizeof(*dir));
#ifdef _WIN32 #if defined(_WIN32)
char* p = malloc(strlen(path) + 2 + 1); char* p = malloc(strlen(path) + 2 + 1);
strcpy(p, path); strcpy(p, path);
if(strchr(path, '/') != NULL) { if(strchr(path, '/') != NULL) {
@ -35,6 +40,22 @@ void* MwDirectoryOpen(const char* path) {
} }
free(p); free(p);
dir->next = 1; dir->next = 1;
#elif defined(__WINDOWS__)
char* p = malloc(strlen(path) + 2 + 1);
strcpy(p, path);
if(strchr(path, '/') != NULL) {
strcat(p, "/");
} else {
strcat(p, "\\");
}
strcat(p, "*.*");
if(_dos_findfirst(p, _A_NORMAL, &dir->result) != 0) {
free(p);
free(dir);
return NULL;
}
free(p);
dir->next = 1;
#elif defined(CLASSIC_MAC_OS) #elif defined(CLASSIC_MAC_OS)
/* todo */ /* todo */
#else #else
@ -51,8 +72,10 @@ void* MwDirectoryOpen(const char* path) {
void MwDirectoryClose(void* handle) { void MwDirectoryClose(void* handle) {
dir_t* dir = handle; dir_t* dir = handle;
#ifdef _WIN32 #if defined(_WIN32)
FindClose(dir->hFind); FindClose(dir->hFind);
#elif defined(__WINDOWS__)
/* nothing? */
#elif defined(CLASSIC_MAC_OS) #elif defined(CLASSIC_MAC_OS)
/* todo */ /* todo */
#else #else
@ -65,7 +88,7 @@ void MwDirectoryClose(void* handle) {
MwDirectoryEntry* MwDirectoryRead(void* handle) { MwDirectoryEntry* MwDirectoryRead(void* handle) {
dir_t* dir = handle; dir_t* dir = handle;
MwDirectoryEntry* entry = malloc(sizeof(*entry)); MwDirectoryEntry* entry = malloc(sizeof(*entry));
#ifdef _WIN32 #if defined(_WIN32)
ULARGE_INTEGER* l; ULARGE_INTEGER* l;
if(!dir->next) return NULL; if(!dir->next) return NULL;
@ -88,6 +111,21 @@ MwDirectoryEntry* MwDirectoryRead(void* handle) {
entry->mtime = l->QuadPart / 10000000 - 11644473600; entry->mtime = l->QuadPart / 10000000 - 11644473600;
dir->next = FindNextFile(dir->hFind, &dir->ffd); dir->next = FindNextFile(dir->hFind, &dir->ffd);
#elif defined(__WINDOWS__)
if(!dir->next) return NULL;
entry->name = MwStringDuplicate(dir->result.name);
if(dir->result.attrib & _A_SUBDIR) {
entry->type = MwDIRECTORY_DIRECTORY;
} else {
entry->type = MwDIRECTORY_FILE;
}
entry->size = dir->result.size;
entry->mtime = MwDosDateTimeToUnix(dir->result.wr_date, dir->result.wr_time);
dir->next = (_dos_findnext(&dir->result) == 0);
#elif defined(CLASSIC_MAC_OS) #elif defined(CLASSIC_MAC_OS)
/* todo */ /* todo */
#else #else
@ -126,7 +164,7 @@ void MwDirectoryFreeEntry(MwDirectoryEntry* entry) {
} }
char* MwDirectoryCurrent(void) { char* MwDirectoryCurrent(void) {
#ifdef _WIN32 #if defined(_WIN32) || defined(__WINDOWS__)
int len = GetCurrentDirectory(0, NULL); int len = GetCurrentDirectory(0, NULL);
char* out = malloc(len); char* out = malloc(len);
@ -140,7 +178,7 @@ char* MwDirectoryCurrent(void) {
#endif #endif
} }
#ifdef _WIN32 #if defined(_WIN32) || defined(__WINDOWS__)
#define DIRSEP '\\' #define DIRSEP '\\'
#else #else
#define DIRSEP '/' #define DIRSEP '/'

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(_WIN32) #if defined(_WIN32) || defined(__WINDOWS__)
void* MwDynamicOpen(const char* path) { void* MwDynamicOpen(const char* path) {
return LoadLibrary(path); return LoadLibrary(path);
} }

View file

@ -1,6 +1,6 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#if defined(_WIN32) #if defined(_WIN32) || defined(__WINDOWS__)
long MwTimeGetTick(void) { long MwTimeGetTick(void) {
return GetTickCount(); return GetTickCount();
} }

View file

@ -8,14 +8,13 @@ typedef struct userdata {
int max_set; int max_set;
} userdata_t; } userdata_t;
#ifndef __WINDOWS__
static struct symtbl { static struct symtbl {
void* lib_dwmapi; void* lib_dwmapi;
HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); HRESULT(WINAPI* DwmSetWindowAttribute)(HWND hwnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute);
} wsymtbl; } wsymtbl;
static int is_plgblt_reliable = 0;
#define DwmSetWindowAttribute wsymtbl.DwmSetWindowAttribute #define DwmSetWindowAttribute wsymtbl.DwmSetWindowAttribute
/* Dark theme detection for classic Windows: check if the user has set their theme to be dark. */ /* Dark theme detection for classic Windows: check if the user has set their theme to be dark. */
@ -62,6 +61,15 @@ static void detect_darktheme(MwLL handle) {
MwLLDispatch(handle, dark_theme, &t); MwLLDispatch(handle, dark_theme, &t);
} }
#endif
/* There isn't any plgblt on Win16 at all */
#ifdef __WINDOWS__
#define is_plgblt_reliable 0
#else
static int is_plgblt_reliable = 0;
#endif
static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) { static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
userdata_t* u = (userdata_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA); userdata_t* u = (userdata_t*)GetWindowLongPtr(hWnd, GWLP_USERDATA);
@ -125,7 +133,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
p.button = MwMOUSE_RIGHT; p.button = MwMOUSE_RIGHT;
} }
SetCapture(NULL); SetCapture(0);
MwLLDispatch(u->ll, up, &p); MwLLDispatch(u->ll, up, &p);
} else if(msg == WM_MOUSEWHEEL) { } else if(msg == WM_MOUSEWHEEL) {
int d = GET_WHEEL_DELTA_WPARAM(wp); int d = GET_WHEEL_DELTA_WPARAM(wp);
@ -182,12 +190,18 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
} else if(msg == WM_CLOSE) { } else if(msg == WM_CLOSE) {
MwLLDispatch(u->ll, close, NULL); MwLLDispatch(u->ll, close, NULL);
} else if(msg == WM_CHAR || msg == WM_SYSCHAR) { } else if(msg == WM_CHAR || msg == WM_SYSCHAR) {
#ifndef __WINDOWS__
int n = wp; int n = wp;
#else
unsigned long n = wp;
#endif
const int base = 'A' - 1; const int base = 'A' - 1;
if(n != 0x1b && n <= 0x1f) { if(n != 0x1b && n <= 0x1f) {
n = (n + base) | MwKEY_CONTROL_FLAG; n = (n + base) | MwKEY_CONTROL_FLAG;
#ifndef __WINDOWS__
if(!(GetKeyState(VK_LSHIFT) || GetKeyState(VK_RSHIFT))) n += 0x20; if(!(GetKeyState(VK_LSHIFT) || GetKeyState(VK_RSHIFT))) n += 0x20;
#endif
} }
if(HIBYTE(VkKeyScan(wp)) & 2) n |= MwKEY_CONTROL_FLAG; if(HIBYTE(VkKeyScan(wp)) & 2) n |= MwKEY_CONTROL_FLAG;
if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG; if(msg == WM_SYSCHAR) n |= MwKEY_ALT_FLAG;
@ -198,7 +212,11 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
} else if(msg == WM_KILLFOCUS) { } else if(msg == WM_KILLFOCUS) {
MwLLDispatch(u->ll, focus_out, NULL); MwLLDispatch(u->ll, focus_out, NULL);
} else if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) { } else if(msg == WM_KEYDOWN || msg == WM_KEYUP || msg == WM_SYSKEYDOWN || msg == WM_SYSKEYUP) {
#ifndef __WINDOWS__
int n = -1; int n = -1;
#else
unsigned long n = -1;
#endif
if(wp == VK_MENU && msg == WM_KEYUP) return 0; if(wp == VK_MENU && msg == WM_KEYUP) return 0;
if(wp == VK_LEFT) n = MwKEY_LEFT; if(wp == VK_LEFT) n = MwKEY_LEFT;
if(wp == VK_RIGHT) n = MwKEY_RIGHT; if(wp == VK_RIGHT) n = MwKEY_RIGHT;
@ -207,8 +225,10 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
if(wp == VK_RETURN) n = MwKEY_ENTER; if(wp == VK_RETURN) n = MwKEY_ENTER;
if(wp == VK_BACK) n = MwKEY_BACKSPACE; if(wp == VK_BACK) n = MwKEY_BACKSPACE;
if(wp == VK_ESCAPE) n = MwKEY_ESCAPE; if(wp == VK_ESCAPE) n = MwKEY_ESCAPE;
#ifndef __WINDOWS__
if(wp == VK_LSHIFT) n = MwKEY_LEFTSHIFT; if(wp == VK_LSHIFT) n = MwKEY_LEFTSHIFT;
if(wp == VK_RSHIFT) n = MwKEY_RIGHTSHIFT; if(wp == VK_RSHIFT) n = MwKEY_RIGHTSHIFT;
#endif
if(wp == VK_MENU) n = MwKEY_ALT; if(wp == VK_MENU) n = MwKEY_ALT;
if(wp == VK_CONTROL) n = MwKEY_CONTROL; if(wp == VK_CONTROL) n = MwKEY_CONTROL;
@ -255,7 +275,7 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
} }
} else if(msg == WM_SETCURSOR) { } else if(msg == WM_SETCURSOR) {
if(LOWORD(lp) != HTCLIENT) return DefWindowProc(hWnd, msg, wp, lp); if(LOWORD(lp) != HTCLIENT) return DefWindowProc(hWnd, msg, wp, lp);
if(u->ll->gdi.cursor != NULL) SetCursor(u->ll->gdi.cursor); if(u->ll->gdi.cursor != 0) SetCursor(u->ll->gdi.cursor);
} else if(msg == WM_USER) { } else if(msg == WM_USER) {
InvalidateRect(hWnd, NULL, FALSE); InvalidateRect(hWnd, NULL, FALSE);
UpdateWindow(hWnd); UpdateWindow(hWnd);
@ -263,9 +283,11 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
char* s = (char*)lp; char* s = (char*)lp;
LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE); LPARAM style = GetWindowLongPtr(hWnd, GWL_STYLE);
#ifndef __WINDOWS__
if(!(style & WS_CHILD)) { if(!(style & WS_CHILD)) {
if(s != NULL && strcmp(s, "ImmersiveColorSet") == 0) detect_darktheme(u->ll); if(s != NULL && strcmp(s, "ImmersiveColorSet") == 0) detect_darktheme(u->ll);
} }
#endif
} else { } else {
return DefWindowProc(hWnd, msg, wp, lp); return DefWindowProc(hWnd, msg, wp, lp);
} }
@ -275,10 +297,16 @@ static LRESULT CALLBACK wndproc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp) {
static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) { static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
MwLL r = malloc(sizeof(*r)); MwLL r = malloc(sizeof(*r));
userdata_t* u = malloc(sizeof(*u)); userdata_t* u = malloc(sizeof(*u));
#ifdef __WINDOWS__
WNDCLASS wc;
#else
WNDCLASSEX wc; WNDCLASSEX wc;
#endif
memset(&wc, 0, sizeof(wc)); memset(&wc, 0, sizeof(wc));
#ifndef __WINDOWS__
wc.cbSize = sizeof(WNDCLASSEX); wc.cbSize = sizeof(WNDCLASSEX);
#endif
wc.style = CS_HREDRAW | CS_VREDRAW; wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = wndproc; wc.lpfnWndProc = wndproc;
wc.cbClsExtra = 0; wc.cbClsExtra = 0;
@ -286,14 +314,22 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
wc.hInstance = (HINSTANCE)GetModuleHandle(NULL); wc.hInstance = (HINSTANCE)GetModuleHandle(NULL);
wc.lpszClassName = "milsko"; wc.lpszClassName = "milsko";
wc.lpszMenuName = NULL; wc.lpszMenuName = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hCursor = LoadCursor(0, IDC_ARROW);
wc.hbrBackground = GetSysColorBrush(COLOR_MENU); wc.hbrBackground = GetSysColorBrush(COLOR_MENU);
#ifndef __WINDOWS__
wc.hIcon = LoadIcon(NULL, IDI_WINLOGO); wc.hIcon = LoadIcon(NULL, IDI_WINLOGO);
wc.hIconSm = NULL; wc.hIconSm = NULL;
#else
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
#endif
MwLLCreateCommon(r); MwLLCreateCommon(r);
#ifdef __WINDOWS__
RegisterClass(&wc);
#else
RegisterClassEx(&wc); RegisterClassEx(&wc);
#endif
r->common.copy_buffer = 1; r->common.copy_buffer = 1;
r->common.type = MwLLBackendGDI; r->common.type = MwLLBackendGDI;
@ -302,12 +338,12 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
if(parent == NULL) r->gdi.get_darktheme = 1; if(parent == NULL) r->gdi.get_darktheme = 1;
r->gdi.force_render = 0; r->gdi.force_render = 0;
r->gdi.grabbed = 0; r->gdi.grabbed = 0;
r->gdi.hWnd = CreateWindow("milsko", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS), x == MwDEFAULT ? CW_USEDEFAULT : x, y == MwDEFAULT ? CW_USEDEFAULT : y, width, height, parent == NULL ? NULL : parent->gdi.hWnd, 0, wc.hInstance, NULL); r->gdi.hWnd = CreateWindow("milsko", "Milsko", parent == NULL ? (WS_OVERLAPPEDWINDOW) : (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS), x == MwDEFAULT ? CW_USEDEFAULT : x, y == MwDEFAULT ? CW_USEDEFAULT : y, width, height, parent == NULL ? 0 : parent->gdi.hWnd, 0, wc.hInstance, NULL);
r->gdi.hInstance = wc.hInstance; r->gdi.hInstance = wc.hInstance;
r->gdi.cursor = NULL; r->gdi.cursor = 0;
r->gdi.icon = NULL; r->gdi.icon = 0;
r->gdi.clip = NULL; r->gdi.clip = 0;
u->ll = r; u->ll = r;
u->min_set = 0; u->min_set = 0;
@ -322,7 +358,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
rc.right = width; rc.right = width;
rc.bottom = height; rc.bottom = height;
AdjustWindowRect(&rc, GetWindowLongPtr(r->gdi.hWnd, GWL_STYLE), FALSE); AdjustWindowRect(&rc, GetWindowLongPtr(r->gdi.hWnd, GWL_STYLE), FALSE);
SetWindowPos(r->gdi.hWnd, NULL, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE); SetWindowPos(r->gdi.hWnd, 0, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, SWP_NOMOVE);
ShowWindow(r->gdi.hWnd, SW_NORMAL); ShowWindow(r->gdi.hWnd, SW_NORMAL);
UpdateWindow(r->gdi.hWnd); UpdateWindow(r->gdi.hWnd);
@ -330,7 +366,7 @@ static MwLL MwLLCreateImpl(MwLL parent, int x, int y, int width, int height) {
InvalidateRect(r->gdi.hWnd, NULL, FALSE); InvalidateRect(r->gdi.hWnd, NULL, FALSE);
} }
SetWindowPos(r->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(r->gdi.hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
return r; return r;
} }
@ -342,9 +378,9 @@ static void MwLLDestroyImpl(MwLL handle) {
SetWindowLongPtr(handle->gdi.hWnd, GWLP_USERDATA, (LPARAM)NULL); SetWindowLongPtr(handle->gdi.hWnd, GWLP_USERDATA, (LPARAM)NULL);
DestroyWindow(handle->gdi.hWnd); DestroyWindow(handle->gdi.hWnd);
if(handle->gdi.clip != NULL) DeleteObject(handle->gdi.clip); if(handle->gdi.clip) DeleteObject(handle->gdi.clip);
if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor); if(handle->gdi.cursor) DestroyCursor(handle->gdi.cursor);
free(handle); free(handle);
} }
@ -396,7 +432,7 @@ static void MwLLLineImpl(MwLL handle, MwPoint* points, MwLLColor color) {
static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) { static MwLLColor MwLLAllocColorImpl(MwLL handle, int r, int g, int b) {
MwLLColor c = malloc(sizeof(*c)); MwLLColor c = malloc(sizeof(*c));
c->gdi.brush = NULL; c->gdi.brush = 0;
MwLLColorUpdate(handle, c, r, g, b); MwLLColorUpdate(handle, c, r, g, b);
@ -413,7 +449,7 @@ static void MwLLColorUpdateImpl(MwLL handle, MwLLColor c, int r, int g, int b) {
if(g < 0) g = 0; if(g < 0) g = 0;
if(b < 0) b = 0; if(b < 0) b = 0;
if(c->gdi.brush != NULL) DeleteObject(c->gdi.brush); if(c->gdi.brush != 0) DeleteObject(c->gdi.brush);
c->gdi.brush = CreateSolidBrush(GetNearestColor(dc, RGB(r, g, b))); c->gdi.brush = CreateSolidBrush(GetNearestColor(dc, RGB(r, g, b)));
c->common.red = r; c->common.red = r;
c->common.green = g; c->common.green = g;
@ -441,12 +477,12 @@ static void MwLLGetXYWHImpl(MwLL handle, int* x, int* y, unsigned int* w, unsign
} }
static void MwLLSetXYImpl(MwLL handle, int x, int y) { static void MwLLSetXYImpl(MwLL handle, int x, int y) {
SetWindowPos(handle->gdi.hWnd, NULL, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER); SetWindowPos(handle->gdi.hWnd, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
} }
static void MwLLSetWHImpl(MwLL handle, int w, int h) { static void MwLLSetWHImpl(MwLL handle, int w, int h) {
SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER); SetWindowPos(handle->gdi.hWnd, 0, 0, 0, w, h, SWP_NOMOVE | SWP_NOZORDER);
InvalidateRect(handle->gdi.hWnd, NULL, FALSE); InvalidateRect(handle->gdi.hWnd, 0, FALSE);
} }
static void MwLLSetTitleImpl(MwLL handle, const char* title) { static void MwLLSetTitleImpl(MwLL handle, const char* title) {
@ -467,11 +503,12 @@ static void MwLLNextEventImpl(MwLL handle) {
(void)handle; (void)handle;
#ifndef __WINDOWS__
if(handle->gdi.get_clipboard) { if(handle->gdi.get_clipboard) {
HGLOBAL hg; HGLOBAL hg;
if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != NULL) { if(OpenClipboard(handle->gdi.hWnd) != 0 && (hg = GetClipboardData(CF_TEXT)) != 0) {
char* txt = malloc(GlobalSize(hg));
char* clp = GlobalLock(hg); char* clp = GlobalLock(hg);
char* txt = malloc(GlobalSize(hg));
strcpy(txt, clp); strcpy(txt, clp);
@ -485,11 +522,15 @@ static void MwLLNextEventImpl(MwLL handle) {
handle->gdi.get_clipboard = 0; handle->gdi.get_clipboard = 0;
} }
#endif
#ifndef __WINDOWS__
if(handle->gdi.get_darktheme) { if(handle->gdi.get_darktheme) {
detect_darktheme(handle); detect_darktheme(handle);
handle->gdi.get_darktheme = 0; handle->gdi.get_darktheme = 0;
} }
#endif
while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) { while(PeekMessage(&msg, handle->gdi.hWnd, 0, 0, PM_NOREMOVE)) {
GetMessage(&msg, handle->gdi.hWnd, 0, 0); GetMessage(&msg, handle->gdi.hWnd, 0, 0);
TranslateMessage(&msg); TranslateMessage(&msg);
@ -500,7 +541,11 @@ static void MwLLNextEventImpl(MwLL handle) {
static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) { static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int width, int height) {
MwLLPixmap r = malloc(sizeof(*r)); MwLLPixmap r = malloc(sizeof(*r));
HDC dc = GetDC(handle->gdi.hWnd); HDC dc = GetDC(handle->gdi.hWnd);
#ifndef __WINDOWS__
BITMAPINFOHEADER bmih; BITMAPINFOHEADER bmih;
#else
BITMAPINFO bmi;
#endif
r->common.raw = malloc(width * height * 4); r->common.raw = malloc(width * height * 4);
memcpy(r->common.raw, data, 4 * width * height); memcpy(r->common.raw, data, 4 * width * height);
@ -508,6 +553,7 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
r->common.width = width; r->common.width = width;
r->common.height = height; r->common.height = height;
#ifndef __WINDOWS__
bmih.biSize = sizeof(bmih); bmih.biSize = sizeof(bmih);
bmih.biWidth = width; bmih.biWidth = width;
bmih.biHeight = -(LONG)height; bmih.biHeight = -(LONG)height;
@ -521,9 +567,15 @@ static MwLLPixmap MwLLCreatePixmapImpl(MwLL handle, unsigned char* data, int wid
bmih.biClrImportant = 0; bmih.biClrImportant = 0;
r->gdi.hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&r->gdi.quad, NULL, (DWORD)0); r->gdi.hBitmap = CreateDIBSection(dc, (BITMAPINFO*)&bmih, DIB_RGB_COLORS, (void**)&r->gdi.quad, NULL, (DWORD)0);
#else
r->gdi.hBitmap = CreateCompatibleBitmap(dc, width, height);
r->gdi.hBitmapMem = CreateCompatibleDC(dc);
SelectObject(r->gdi.hBitmapMem, r->gdi.hBitmap);
SetDIBits(r->gdi.hBitmapMem, r->gdi.hBitmap, 0, height, r->common.raw, &bmi, DIB_RGB_COLORS);
#endif
r->gdi.hMask = NULL; r->gdi.hMask = 0;
r->gdi.hMask2 = NULL; r->gdi.hMask2 = 0;
ReleaseDC(handle->gdi.hWnd, dc); ReleaseDC(handle->gdi.hWnd, dc);
@ -563,8 +615,8 @@ static void MwLLPixmapUpdateImpl(MwLLPixmap r) {
} }
} }
if(r->gdi.hMask != NULL) DeleteObject(r->gdi.hMask); if(r->gdi.hMask != 0) DeleteObject(r->gdi.hMask);
if(r->gdi.hMask2 != NULL) DeleteObject(r->gdi.hMask2); if(r->gdi.hMask2 != 0) DeleteObject(r->gdi.hMask2);
r->gdi.hMask = CreateBitmap(r->common.width, r->common.height, 1, 1, words); r->gdi.hMask = CreateBitmap(r->common.width, r->common.height, 1, 1, words);
r->gdi.hMask2 = CreateBitmap(r->common.width, r->common.height, 1, 1, words2); r->gdi.hMask2 = CreateBitmap(r->common.width, r->common.height, 1, 1, words2);
@ -598,18 +650,27 @@ static void MwLLDrawPixmapImpl(MwLL handle, MwRect* rect, MwLLPixmap pixmap) {
SelectObject(hmdc, pixmap->gdi.hBitmap); SelectObject(hmdc, pixmap->gdi.hBitmap);
#ifndef __WINDOWS__
if(!is_plgblt_reliable || PlgBlt(handle->gdi.hDC, p, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, pixmap->gdi.hMask, 0, 0) == 0) { if(!is_plgblt_reliable || PlgBlt(handle->gdi.hDC, p, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, pixmap->gdi.hMask, 0, 0) == 0) {
#endif
SelectObject(hmdc, pixmap->gdi.hMask2); SelectObject(hmdc, pixmap->gdi.hMask2);
StretchBlt(handle->gdi.hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, SRCAND); StretchBlt(handle->gdi.hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, SRCAND);
SelectObject(hmdc, pixmap->gdi.hBitmap); SelectObject(hmdc, pixmap->gdi.hBitmap);
StretchBlt(handle->gdi.hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, SRCPAINT); StretchBlt(handle->gdi.hDC, rect->x, rect->y, rect->width, rect->height, hmdc, 0, 0, pixmap->common.width, pixmap->common.height, SRCPAINT);
#ifndef __WINDOWS__
} }
#endif
DeleteDC(hmdc); DeleteDC(hmdc);
} }
static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) { static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
/* it's probably (presumably) not possible to set the icon on 16-bit windows */
#ifdef __WINDOWS__
(void)handle;
(void)pixmap;
#else
ICONINFO ii; ICONINFO ii;
memset(&ii, 0, sizeof(ii)); memset(&ii, 0, sizeof(ii));
@ -623,6 +684,7 @@ static void MwLLSetIconImpl(MwLL handle, MwLLPixmap pixmap) {
handle->gdi.icon = CreateIconIndirect(&ii); handle->gdi.icon = CreateIconIndirect(&ii);
SendMessage(handle->gdi.hWnd, WM_SETICON, ICON_SMALL, (LPARAM)handle->gdi.icon); SendMessage(handle->gdi.hWnd, WM_SETICON, ICON_SMALL, (LPARAM)handle->gdi.icon);
SendMessage(handle->gdi.hWnd, WM_SETICON, ICON_BIG, (LPARAM)handle->gdi.icon); SendMessage(handle->gdi.hWnd, WM_SETICON, ICON_BIG, (LPARAM)handle->gdi.icon);
#endif
} }
static void MwLLForceRenderImpl(MwLL handle) { static void MwLLForceRenderImpl(MwLL handle) {
@ -683,12 +745,20 @@ HCURSOR MwLLGDICreateCursor(MwCursor* image, MwCursor* mask) {
} }
static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) { static void MwLLSetCursorImpl(MwLL handle, MwCursor* image, MwCursor* mask) {
if(image && mask) {
HCURSOR cursor = MwLLGDICreateCursor(image, mask); HCURSOR cursor = MwLLGDICreateCursor(image, mask);
if(handle->gdi.cursor != NULL) DestroyCursor(handle->gdi.cursor); if(handle->gdi.cursor != 0) DestroyCursor(handle->gdi.cursor);
if(handle->gdi.icon != NULL) DestroyIcon(handle->gdi.icon); if(handle->gdi.icon != 0) DestroyIcon(handle->gdi.icon);
handle->gdi.cursor = cursor; handle->gdi.cursor = cursor;
} }
/* Only on Win16: hide the cursor outright if image/mask are null */
#ifndef __WINDOWS__
else if(!image && !mask) {
ShowCursor(FALSE);
}
#endif
}
static void MwLLDetachImpl(MwLL handle, MwPoint* point) { static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
RECT rc, rc2; RECT rc, rc2;
@ -701,12 +771,16 @@ static void MwLLDetachImpl(MwLL handle, MwPoint* point) {
GetClientRect(handle->gdi.hWnd, &rc2); GetClientRect(handle->gdi.hWnd, &rc2);
#ifdef __WINDOWS__
if(lp2 & WS_POPUP) {
#else
if(lp2 & WS_EX_TOOLWINDOW) { if(lp2 & WS_EX_TOOLWINDOW) {
#endif
SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp); SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp);
} else { } else {
SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)WS_OVERLAPPEDWINDOW | lp); SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)WS_OVERLAPPEDWINDOW | lp);
} }
SetParent(handle->gdi.hWnd, NULL); SetParent(handle->gdi.hWnd, 0);
rc.left += point->x; rc.left += point->x;
rc.top += point->y; rc.top += point->y;
@ -752,7 +826,7 @@ static void MwLLMakeBorderlessImpl(MwLL handle, int toggle) {
SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, lp); SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, lp);
SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); SetWindowPos(handle->gdi.hWnd, 0, 0, 0, 0, 0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER);
} }
static void MwLLFocusImpl(MwLL handle) { static void MwLLFocusImpl(MwLL handle) {
@ -789,6 +863,11 @@ static void MwLLGrabPointerImpl(MwLL handle, int toggle) {
} }
static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) { static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_type) {
#ifdef __WINDOWS__
(void)handle;
(void)text;
(void)clipboard_type;
#else
HGLOBAL hg; HGLOBAL hg;
(void)clipboard_type; (void)clipboard_type;
if(OpenClipboard(handle->gdi.hWnd) != 0) { if(OpenClipboard(handle->gdi.hWnd) != 0) {
@ -805,6 +884,7 @@ static void MwLLSetClipboardImpl(MwLL handle, const char* text, int clipboard_ty
CloseClipboard(); CloseClipboard();
} }
#endif
} }
static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) { static void MwLLGetClipboardImpl(MwLL handle, int clipboard_type) {
@ -818,14 +898,17 @@ static void MwLLMakeToolWindowImpl(MwLL handle) {
int w, h; int w, h;
SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp); SetWindowLongPtr(handle->gdi.hWnd, GWL_STYLE, (LPARAM)lp);
#ifdef __WINDOWS__
SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_POPUP);
#else
SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW); SetWindowLongPtr(handle->gdi.hWnd, GWL_EXSTYLE, (LPARAM)WS_EX_TOOLWINDOW);
#endif
GetClientRect(handle->gdi.hWnd, &rc); GetClientRect(handle->gdi.hWnd, &rc);
w = rc.right - rc.left; w = rc.right - rc.left;
h = rc.bottom - rc.top; h = rc.bottom - rc.top;
SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, w, h, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER); SetWindowPos(handle->gdi.hWnd, 0, 0, 0, w, h, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
} }
static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) { static void MwLLGetCursorCoordImpl(MwLL handle, MwPoint* point) {
@ -860,13 +943,21 @@ static void MwLLEndStateChangeImpl(MwLL handle) {
} }
static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) { static void MwLLSetDarkThemeImpl(MwLL handle, int toggle) {
#ifdef __WINDOWS__
(void)handle;
(void)toggle;
#else
BOOL v = toggle ? TRUE : FALSE; BOOL v = toggle ? TRUE : FALSE;
if(DwmSetWindowAttribute) if(DwmSetWindowAttribute)
DwmSetWindowAttribute(handle->gdi.hWnd, 20, &v, sizeof(v)); DwmSetWindowAttribute(handle->gdi.hWnd, 20, &v, sizeof(v));
#endif
} }
static MwBool MwLLDoModernImpl(MwLL handle) { static MwBool MwLLDoModernImpl(MwLL handle) {
#ifdef __WINDOWS__
return MwFALSE;
#else
OSVERSIONINFO osvi; OSVERSIONINFO osvi;
(void)handle; (void)handle;
@ -880,34 +971,35 @@ static MwBool MwLLDoModernImpl(MwLL handle) {
} }
return MwTRUE; return MwTRUE;
#endif
} }
static void MwLLRaiseImpl(MwLL handle) { static void MwLLRaiseImpl(MwLL handle) {
SetWindowPos(handle->gdi.hWnd, NULL, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE); SetWindowPos(handle->gdi.hWnd, 0, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
} }
static void MwLLClipImpl(MwLL handle, MwRect* rect) { static void MwLLClipImpl(MwLL handle, MwRect* rect) {
if(rect == NULL) { if(rect == NULL) {
SelectClipRgn(handle->gdi.hDC, NULL); SelectClipRgn(handle->gdi.hDC, 0);
if(handle->gdi.clip != NULL) { if(handle->gdi.clip) {
DeleteObject(handle->gdi.clip); DeleteObject(handle->gdi.clip);
handle->gdi.clip = NULL; handle->gdi.clip = 0;
} }
} else { } else {
HRGN clip = CreateRectRgn(rect->x, rect->y, rect->x + rect->width, rect->y + rect->height); HRGN clip = CreateRectRgn(rect->x, rect->y, rect->x + rect->width, rect->y + rect->height);
SelectClipRgn(handle->gdi.hDC, clip); SelectClipRgn(handle->gdi.hDC, clip);
if(handle->gdi.clip != NULL) DeleteObject(handle->gdi.clip); if(handle->gdi.clip != 0) DeleteObject(handle->gdi.clip);
handle->gdi.clip = clip; handle->gdi.clip = clip;
} }
} }
static int MwLLGDICallInitImpl(void) { static int MwLLGDICallInitImpl(void) {
#ifndef __WINDOWS__
void* ntdll; void* ntdll;
memset(&wsymtbl, 0, sizeof(wsymtbl)); memset(&wsymtbl, 0, sizeof(wsymtbl));
wsymtbl.lib_dwmapi = MwDynamicOpen("dwmapi.dll"); wsymtbl.lib_dwmapi = MwDynamicOpen("dwmapi.dll");
@ -919,6 +1011,7 @@ static int MwLLGDICallInitImpl(void) {
} else { } else {
is_plgblt_reliable = 1; is_plgblt_reliable = 1;
} }
#endif
/* TODO: check properly */ /* TODO: check properly */
return 0; return 0;

File diff suppressed because it is too large Load diff

View file

@ -881,11 +881,17 @@ void MwVaListApply(MwWidget handle, va_list va) {
} }
void MwSetDefault(MwWidget handle) { void MwSetDefault(MwWidget handle) {
#ifndef __WINDOWS__
if(handle->lowlevel != NULL) MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask); if(handle->lowlevel != NULL) MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask);
#endif
} }
void MwHideCursor(MwWidget handle) { void MwHideCursor(MwWidget handle) {
#ifndef __WINDOWS__
MwLLSetCursor(handle->lowlevel, &MwCursorHidden, &MwCursorHiddenMask); MwLLSetCursor(handle->lowlevel, &MwCursorHidden, &MwCursorHiddenMask);
#else
MwLLSetCursor(handle->lowlevel, NULL, NULL);
#endif
} }
void MwDispatchUserHandler(MwWidget handle, const char* key, void* handler_data) { void MwDispatchUserHandler(MwWidget handle, const char* key, void* handler_data) {
@ -934,10 +940,14 @@ void MwDispatchError(int code, const char* message) {
if(error_handler != NULL) { if(error_handler != NULL) {
error_handler(code, message, error_user_data); error_handler(code, message, error_user_data);
} else { } else {
#ifdef _WIN32 #if defined(_WIN32) || defined(__WINDOWS__)
char buffer[1024]; char buffer[1024];
MwStringPrintIntoBuffer(buffer, 1024, "Error: %s\r\nCode : %d\r\n\r\nMilsko is exiting.", message, code); MwStringPrintIntoBuffer(buffer, 1024, "Error: %s\r\nCode : %d\r\n\r\nMilsko is exiting.", message, code);
#if defined(__WINDOWS__)
MessageBox(NULL, buffer, "Error", MB_ICONHAND | MB_OK);
#else
MessageBox(NULL, buffer, "Error", MB_ICONERROR | MB_OK); MessageBox(NULL, buffer, "Error", MB_ICONERROR | MB_OK);
#endif
#else #else
fprintf(stderr, "Error: %s\nCode : %d\n\nMilsko is exiting.", message, code); fprintf(stderr, "Error: %s\nCode : %d\n\nMilsko is exiting.", message, code);
#endif #endif
@ -1019,7 +1029,9 @@ int MwLibraryInit(void) {
MwColorTableInit(); MwColorTableInit();
#ifndef __WINDOWS__
MwFLSetup(); MwFLSetup();
#endif
for(i = 0; calls[i] != NULL; i++) { for(i = 0; calls[i] != NULL; i++) {
if(calls[i]() == 0) return 0; if(calls[i]() == 0) return 0;

View file

@ -1,5 +1,7 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#ifndef __WINDOWS__
#define WIN_SIZE 464 #define WIN_SIZE 464
#define PICKER_SIZE 364 #define PICKER_SIZE 364
#define IMG_POS_X(w) ((w - PICKER_SIZE) / 2) #define IMG_POS_X(w) ((w - PICKER_SIZE) / 2)
@ -378,3 +380,5 @@ MwWidget MwColorPicker(MwWidget handle, const char* title) {
return window; return window;
} }
#endif

View file

@ -1,5 +1,7 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#ifndef __WINDOWS__
#include "../external/stb_ds.h" #include "../external/stb_ds.h"
typedef struct filechooser { typedef struct filechooser {
@ -507,6 +509,7 @@ static void scan(MwWidget handle, const char* path, int record) {
static void setup_fallback_filechooser(MwWidget window, int dir) { static void setup_fallback_filechooser(MwWidget window, int dir) {
char* path; char* path;
MwLLPixmap icon; MwLLPixmap icon;
filechooser_t* fc = malloc(sizeof(*fc)); filechooser_t* fc = malloc(sizeof(*fc));
memset(fc, 0, sizeof(*fc)); memset(fc, 0, sizeof(*fc));
@ -568,6 +571,32 @@ MwWidget MwFileChooserEx(MwWidget handle, const char* title, int dir) {
return window; return window;
} }
#else
MwWidget MwFileChooserEx(MwWidget handle, const char* title, int dir) {
MwWidget window;
int w, h;
int wx;
int wy;
w = 700;
h = w * 2 / 3;
if(handle == NULL) {
wx = wy = MwDEFAULT;
} else {
wx = MwGetInteger(handle, MwNx) + (MwGetInteger(handle, MwNwidth) - w) / 2;
wy = MwGetInteger(handle, MwNy) + (MwGetInteger(handle, MwNheight) - h) / 2;
}
window = MwVaCreateWidget(MwWindowClass, "filechooser", NULL, wx, wy, w, h,
MwNtitle, title,
NULL);
if(handle != NULL) MwReparent(window, handle);
return window;
}
#endif
MwWidget MwFileChooser(MwWidget handle, const char* title) { MwWidget MwFileChooser(MwWidget handle, const char* title) {
return MwFileChooserEx(handle, title, 0); return MwFileChooserEx(handle, title, 0);
} }

View file

@ -70,7 +70,9 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi
if((flag & MwMB_ICONMASK) != 0) { if((flag & MwMB_ICONMASK) != 0) {
MwWidget icon; MwWidget icon;
MwLLPixmap px; MwLLPixmap px;
unsigned int* data = NULL; MwU32* data = NULL;
#ifndef __WINDOWS__
icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48); icon = MwCreateWidget(MwImageClass, "image", window, 8, (h - 48) / 2, 48, 48);
@ -110,6 +112,7 @@ MwWidget MwMessageBox(MwWidget handle, const char* text, const char* title, unsi
px = MwLoadIcon(icon, data); px = MwLoadIcon(icon, data);
MwSetVoid(icon, MwNpixmap, px); MwSetVoid(icon, MwNpixmap, px);
#endif
left = 8 + 48 + 8; left = 8 + 48 + 8;
} }

View file

@ -115,6 +115,7 @@ void MwDrawRect(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPolygon(handle->lowlevel, p, 4, color); MwLLPolygon(handle->lowlevel, p, 4, color);
} }
#ifndef __WINDOWS__
void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) { void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
MwLLPixmap pixmap; MwLLPixmap pixmap;
int y; int y;
@ -153,6 +154,7 @@ void MwDrawRectFading(MwWidget handle, MwRect* rect, MwLLColor color) {
free(data); free(data);
} }
#endif
void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { void MwDrawFrame(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
MwDrawFrameWithBorder(handle, rect, color, invert, MwDefaultBorderWidth(handle)); MwDrawFrameWithBorder(handle, rect, color, invert, MwDefaultBorderWidth(handle));
@ -220,12 +222,17 @@ void MwDrawWidgetBack(MwWidget handle, MwRect* rect, MwLLColor color, int invert
col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color; col = invert ? MwLightenColor(handle, color, -8, -8, -8) : color;
color_set_disabled_if_disabled(handle, col); color_set_disabled_if_disabled(handle, col);
#ifndef __WINDOWS__
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
MwDrawRectFading(handle, rect, col); MwDrawRectFading(handle, rect, col);
} else { } else
#else
{
MwDrawRect(handle, rect, col); MwDrawRect(handle, rect, col);
} }
if(col != color) MwLLFreeColor(col); #endif
if(col != color)
MwLLFreeColor(col);
} }
void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) { void MwDrawDiamond(MwWidget handle, MwRect* rect, MwLLColor color, int invert) {
@ -352,6 +359,7 @@ static void MwDrawFrameEx_simple(MwWidget handle, MwRect* rect, MwLLColor color,
rect->height -= border * 2; rect->height -= border * 2;
} }
#ifndef __WINDOWS__
static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighter, MwLLColor darker, int invert, int border, int diff, int same) { static void frame_border_complex(MwWidget handle, MwRect* rect, MwLLColor lighter, MwLLColor darker, int invert, int border, int diff, int same) {
MwPoint p[7]; MwPoint p[7];
@ -423,13 +431,17 @@ static void MwDrawFrameEx_complex(MwWidget handle, MwRect* rect, MwLLColor color
rect->width -= border * 2; rect->width -= border * 2;
rect->height -= border * 2; rect->height -= border * 2;
} }
#endif
void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) { void MwDrawFrameEx(MwWidget handle, MwRect* rect, MwLLColor color, int invert, int border, int diff, int same) {
border = translate_border(handle, border); border = translate_border(handle, border);
#ifndef __WINDOWS__
if(MwGetInteger(handle, MwNmodernLook)) { if(MwGetInteger(handle, MwNmodernLook)) {
MwDrawFrameEx_complex(handle, rect, color, invert, border, diff, same); MwDrawFrameEx_complex(handle, rect, color, invert, border, diff, same);
} else { } else
#endif
{
MwDrawFrameEx_simple(handle, rect, color, invert, border, diff, same); MwDrawFrameEx_simple(handle, rect, color, invert, border, diff, same);
} }
} }
@ -894,6 +906,7 @@ typedef struct color {
int a; int a;
} color_t; } color_t;
#ifndef __WINDOWS__
MwLLPixmap MwLoadXPM(MwWidget handle, char** data) { MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
int col, row, colors, cpp; int col, row, colors, cpp;
unsigned char* rgb; unsigned char* rgb;
@ -966,3 +979,4 @@ MwLLPixmap MwLoadXPM(MwWidget handle, char** data) {
return px; return px;
} }
#endif

View file

@ -1,12 +1,14 @@
#include <Mw/Milsko.h> #include <Mw/Milsko.h>
#ifndef __WINDOWS
int (*MwFLDrawText)(MwWidget handle, MwFLFont font, MwPoint* point, const char* text, MwLLColor color) = NULL; int (*MwFLDrawText)(MwWidget handle, MwFLFont font, MwPoint* point, const char* text, MwLLColor color) = NULL;
int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL; int (*MwFLTextWidth)(MwFLFont font, const char* text) = NULL;
int (*MwFLTextHeight)(MwFLFont font, int count) = NULL; int (*MwFLTextHeight)(MwFLFont font, int count) = NULL;
void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL; void* (*MwFLFontLoad)(unsigned char* data, unsigned int size, int px) = NULL;
void (*MwFLFontFree)(void* handle) = NULL; void (*MwFLFontFree)(void* handle) = NULL;
#endif
#if defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE) #if (defined(USE_FREETYPE2) || defined(USE_STB_TRUETYPE)) && !defined(__WINDOWS__)
#define TTF #define TTF
#endif #endif
@ -292,6 +294,7 @@ static void bitmap_MwDrawText(MwWidget handle, MwPoint* point, const char* text,
free(px); free(px);
} }
#ifndef __INWDOWS__
typedef int (*call_t)(void); typedef int (*call_t)(void);
void MwFLSetup(void) { void MwFLSetup(void) {
call_t calls[] = { call_t calls[] = {
@ -308,3 +311,4 @@ void MwFLSetup(void) {
if(calls[i]() == 0) return; if(calls[i]() == 0) return;
} }
} }
#endif

View file

@ -102,7 +102,9 @@ static void click(MwWidget handle) {
if(ent > arrlen(cb->list)) ent = arrlen(cb->list); if(ent > arrlen(cb->list)) ent = arrlen(cb->list);
#ifndef __WINDOWS__
MwLLSetCursor(handle->lowlevel, &MwCursorArrow, &MwCursorArrowMask); MwLLSetCursor(handle->lowlevel, &MwCursorArrow, &MwCursorArrowMask);
#endif
for(i = 0; i < arrlen(cb->list); i++) { for(i = 0; i < arrlen(cb->list); i++) {
int l = MwTextWidth(handle, NULL, cb->list[i]) + MwDefaultBorderWidth(handle) * 2; int l = MwTextWidth(handle, NULL, cb->list[i]) + MwDefaultBorderWidth(handle) * 2;
@ -113,7 +115,9 @@ static void click(MwWidget handle) {
MwNsingleClickSelectable, 1, MwNsingleClickSelectable, 1,
NULL); NULL);
#ifndef __WINDOWS__
MwLLSetCursor(((MwListBox)cb->listbox->internal)->frame->lowlevel, &MwCursorArrow, &MwCursorArrowMask); MwLLSetCursor(((MwListBox)cb->listbox->internal)->frame->lowlevel, &MwCursorArrow, &MwCursorArrowMask);
#endif
for(i = 0; i < arrlen(cb->list); i++) { for(i = 0; i < arrlen(cb->list); i++) {
MwListBoxSet(cb->listbox, -1, 0, cb->list[i]); MwListBoxSet(cb->listbox, -1, 0, cb->list[i]);
@ -128,7 +132,9 @@ static void click(MwWidget handle) {
MwLLMakeToolWindow(cb->listbox->lowlevel); MwLLMakeToolWindow(cb->listbox->lowlevel);
MwLLEndStateChange(cb->listbox->lowlevel); MwLLEndStateChange(cb->listbox->lowlevel);
} else { } else {
#ifndef __WINDOWS__
MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask); MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask);
#endif
if(cb->listbox != NULL) { if(cb->listbox != NULL) {
MwDestroyWidget(cb->listbox); MwDestroyWidget(cb->listbox);

View file

@ -10,7 +10,9 @@ static int wcreate(MwWidget handle) {
MwSetDefault(handle); MwSetDefault(handle);
#ifndef __WINDOWS__
MwLLSetCursor(handle->lowlevel, &MwCursorText, &MwCursorTextMask); MwLLSetCursor(handle->lowlevel, &MwCursorText, &MwCursorTextMask);
#endif
return 0; return 0;
} }

View file

@ -4,6 +4,11 @@
#define Spacing 1 #define Spacing 1
/* 16 bit windows */
#ifdef __WINDOWS__
#define HAVE_SEVEN_SEGMENT 0
#endif
static int wcreate(MwWidget handle) { static int wcreate(MwWidget handle) {
MwLabel lab = malloc(sizeof(*lab)); MwLabel lab = malloc(sizeof(*lab));
memset(lab, 0, sizeof(*lab)); memset(lab, 0, sizeof(*lab));
@ -122,6 +127,7 @@ static void draw_h(MwWidget handle, unsigned char* raw, int x, int y, int stride
} }
} }
#ifndef HAVE_SEVEN_SEGMENT
static void draw_seven_segment(MwWidget handle) { static void draw_seven_segment(MwWidget handle) {
MwRect r; MwRect r;
MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground)); MwLLColor base = MwParseColor(handle, MwGetText(handle, MwNbackground));
@ -311,6 +317,7 @@ static void draw_seven_segment(MwWidget handle) {
MwLLDestroyPixmap(px); MwLLDestroyPixmap(px);
} }
#endif
static void draw_normal(MwWidget handle) { static void draw_normal(MwWidget handle) {
MwRect r; MwRect r;
@ -377,9 +384,11 @@ static void prop_change(MwWidget handle, const char* key) {
if(strcmp(key, MwNsevenSegment) == 0) { if(strcmp(key, MwNsevenSegment) == 0) {
MwLabel lab = handle->internal; MwLabel lab = handle->internal;
#ifndef HAVE_SEVEN_SEGMENT
if(MwGetInteger(handle, MwNsevenSegment)) if(MwGetInteger(handle, MwNsevenSegment))
lab->draw = draw_seven_segment; lab->draw = draw_seven_segment;
else else
#endif
lab->draw = draw_normal; lab->draw = draw_normal;
} }
} }

View file

@ -85,11 +85,13 @@ static void key(MwWidget handle, int code) {
static void mouse_move(MwWidget handle) { static void mouse_move(MwWidget handle) {
MwEntry e = handle->internal; MwEntry e = handle->internal;
int w = MwGetInteger(handle, MwNwidth); int w = MwGetInteger(handle, MwNwidth);
#ifndef __WINDOWS__
if(handle->mouse_point.x >= (w - e->right)) { if(handle->mouse_point.x >= (w - e->right)) {
MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask); MwLLSetCursor(handle->lowlevel, &MwCursorDefault, &MwCursorDefaultMask);
} else { } else {
MwLLSetCursor(handle->lowlevel, &MwCursorText, &MwCursorTextMask); MwLLSetCursor(handle->lowlevel, &MwCursorText, &MwCursorTextMask);
} }
#endif
} }
static void mouse_up(MwWidget handle, void* ptr) { static void mouse_up(MwWidget handle, void* ptr) {