aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/common
diff options
context:
space:
mode:
authorStapleButter <thetotalworm@gmail.com>2017-09-09 02:30:51 +0200
committerStapleButter <thetotalworm@gmail.com>2017-09-09 02:30:51 +0200
commit70e4841d311d68689724768157cc9cbfbde7a9fc (patch)
treeba9499f77d1258530a7e60aa6e1732c41d98161c /src/libui_sdl/libui/common
parent81747d6c34eb159481a6ca3f283d065fa3568617 (diff)
another UI attempt, I guess.
sorry.
Diffstat (limited to 'src/libui_sdl/libui/common')
-rw-r--r--src/libui_sdl/libui/common/CMakeLists.txt16
-rw-r--r--src/libui_sdl/libui/common/areaevents.c167
-rw-r--r--src/libui_sdl/libui/common/control.c101
-rw-r--r--src/libui_sdl/libui/common/controlsigs.h25
-rw-r--r--src/libui_sdl/libui/common/debug.c21
-rw-r--r--src/libui_sdl/libui/common/matrix.c50
-rw-r--r--src/libui_sdl/libui/common/shouldquit.c22
-rw-r--r--src/libui_sdl/libui/common/uipriv.h58
-rw-r--r--src/libui_sdl/libui/common/userbugs.c8
9 files changed, 468 insertions, 0 deletions
diff --git a/src/libui_sdl/libui/common/CMakeLists.txt b/src/libui_sdl/libui/common/CMakeLists.txt
new file mode 100644
index 0000000..91d7949
--- /dev/null
+++ b/src/libui_sdl/libui/common/CMakeLists.txt
@@ -0,0 +1,16 @@
+# 3 june 2016
+
+list(APPEND _LIBUI_SOURCES
+ common/areaevents.c
+ common/control.c
+ common/debug.c
+ common/matrix.c
+ common/shouldquit.c
+ common/userbugs.c
+)
+set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
+
+list(APPEND _LIBUI_INCLUDEDIRS
+ common
+)
+set(_LIBUI_INCLUDEDIRS ${_LIBUI_INCLUDEDIRS} PARENT_SCOPE)
diff --git a/src/libui_sdl/libui/common/areaevents.c b/src/libui_sdl/libui/common/areaevents.c
new file mode 100644
index 0000000..cf3c288
--- /dev/null
+++ b/src/libui_sdl/libui/common/areaevents.c
@@ -0,0 +1,167 @@
+// 29 march 2014
+#include "../ui.h"
+#include "uipriv.h"
+
+/*
+Windows and GTK+ have a limit of 2 and 3 clicks, respectively, natively supported. Fortunately, we can simulate the double/triple-click behavior to build higher-order clicks. We can use the same algorithm Windows uses on both:
+ http://blogs.msdn.com/b/oldnewthing/archive/2004/10/18/243925.aspx
+For GTK+, we pull the double-click time and double-click distance, which work the same as the equivalents on Windows (so the distance is in all directions), from the GtkSettings system.
+
+On GTK+ this will also allow us to discard the GDK_BUTTON_2PRESS and GDK_BUTTON_3PRESS events, so the button press stream will be just like on other platforms.
+
+Thanks to mclasen, garnacho_, halfline, and tristan in irc.gimp.net/#gtk+.
+*/
+
+// x, y, xdist, ydist, and c.rect must have the same units
+// so must time, maxTime, and c.prevTime
+int clickCounterClick(clickCounter *c, int button, int x, int y, uintptr_t time, uintptr_t maxTime, int32_t xdist, int32_t ydist)
+{
+ // different button than before? if so, don't count
+ if (button != c->curButton)
+ c->count = 0;
+
+ // (x, y) in the allowed region for a double-click? if not, don't count
+ if (x < c->rectX0)
+ c->count = 0;
+ if (y < c->rectY0)
+ c->count = 0;
+ if (x >= c->rectX1)
+ c->count = 0;
+ if (y >= c->rectY1)
+ c->count = 0;
+
+ // too slow? if so, don't count
+ // note the below expression; time > (c.prevTime + maxTime) can overflow!
+ if ((time - c->prevTime) > maxTime) // too slow; don't count
+ c->count = 0;
+
+ c->count++; // if either of the above ifs happened, this will make the click count 1; otherwise it will make the click count 2, 3, 4, 5, ...
+
+ // now we need to update the internal structures for the next test
+ c->curButton = button;
+ c->prevTime = time;
+ c->rectX0 = x - xdist;
+ c->rectY0 = y - ydist;
+ c->rectX1 = x + xdist;
+ c->rectY1 = y + ydist;
+
+ return c->count;
+}
+
+void clickCounterReset(clickCounter *c)
+{
+ c->curButton = 0;
+ c->rectX0 = 0;
+ c->rectY0 = 0;
+ c->rectX1 = 0;
+ c->rectY1 = 0;
+ c->prevTime = 0;
+ c->count = 0;
+}
+
+/*
+For position independence across international keyboard layouts, typewriter keys are read using scancodes (which are always set 1).
+Windows provides the scancodes directly in the LPARAM.
+GTK+ provides the scancodes directly from the underlying window system via GdkEventKey.hardware_keycode.
+On X11, this is scancode + 8 (because X11 keyboard codes have a range of [8,255]).
+Wayland is guaranteed to give the same result (thanks ebassi in irc.gimp.net/#gtk+).
+On Linux, where evdev is used instead of polling scancodes directly from the keyboard, evdev's typewriter section key code constants are the same as scancodes anyway, so the rules above apply.
+Typewriter section scancodes are the same across international keyboards with some exceptions that have been accounted for (see KeyEvent's documentation); see http://www.quadibloc.com/comp/scan.htm for details.
+Non-typewriter keys can be handled safely using constants provided by the respective backend API.
+
+Because GTK+ keysyms may or may not obey Num Lock, we also handle the 0-9 and . keys on the numeric keypad with scancodes (they match too).
+*/
+
+// use uintptr_t to be safe; the size of the scancode/hardware key code field on each platform is different
+static const struct {
+ uintptr_t scancode;
+ char equiv;
+} scancodeKeys[] = {
+ { 0x02, '1' },
+ { 0x03, '2' },
+ { 0x04, '3' },
+ { 0x05, '4' },
+ { 0x06, '5' },
+ { 0x07, '6' },
+ { 0x08, '7' },
+ { 0x09, '8' },
+ { 0x0A, '9' },
+ { 0x0B, '0' },
+ { 0x0C, '-' },
+ { 0x0D, '=' },
+ { 0x0E, '\b' },
+ { 0x0F, '\t' },
+ { 0x10, 'q' },
+ { 0x11, 'w' },
+ { 0x12, 'e' },
+ { 0x13, 'r' },
+ { 0x14, 't' },
+ { 0x15, 'y' },
+ { 0x16, 'u' },
+ { 0x17, 'i' },
+ { 0x18, 'o' },
+ { 0x19, 'p' },
+ { 0x1A, '[' },
+ { 0x1B, ']' },
+ { 0x1C, '\n' },
+ { 0x1E, 'a' },
+ { 0x1F, 's' },
+ { 0x20, 'd' },
+ { 0x21, 'f' },
+ { 0x22, 'g' },
+ { 0x23, 'h' },
+ { 0x24, 'j' },
+ { 0x25, 'k' },
+ { 0x26, 'l' },
+ { 0x27, ';' },
+ { 0x28, '\'' },
+ { 0x29, '`' },
+ { 0x2B, '\\' },
+ { 0x2C, 'z' },
+ { 0x2D, 'x' },
+ { 0x2E, 'c' },
+ { 0x2F, 'v' },
+ { 0x30, 'b' },
+ { 0x31, 'n' },
+ { 0x32, 'm' },
+ { 0x33, ',' },
+ { 0x34, '.' },
+ { 0x35, '/' },
+ { 0x39, ' ' },
+ { 0xFFFF, 0 },
+};
+
+static const struct {
+ uintptr_t scancode;
+ uiExtKey equiv;
+} scancodeExtKeys[] = {
+ { 0x47, uiExtKeyN7 },
+ { 0x48, uiExtKeyN8 },
+ { 0x49, uiExtKeyN9 },
+ { 0x4B, uiExtKeyN4 },
+ { 0x4C, uiExtKeyN5 },
+ { 0x4D, uiExtKeyN6 },
+ { 0x4F, uiExtKeyN1 },
+ { 0x50, uiExtKeyN2 },
+ { 0x51, uiExtKeyN3 },
+ { 0x52, uiExtKeyN0 },
+ { 0x53, uiExtKeyNDot },
+ { 0xFFFF, 0 },
+};
+
+int fromScancode(uintptr_t scancode, uiAreaKeyEvent *ke)
+{
+ int i;
+
+ for (i = 0; scancodeKeys[i].scancode != 0xFFFF; i++)
+ if (scancodeKeys[i].scancode == scancode) {
+ ke->Key = scancodeKeys[i].equiv;
+ return 1;
+ }
+ for (i = 0; scancodeExtKeys[i].scancode != 0xFFFF; i++)
+ if (scancodeExtKeys[i].scancode == scancode) {
+ ke->ExtKey = scancodeExtKeys[i].equiv;
+ return 1;
+ }
+ return 0;
+}
diff --git a/src/libui_sdl/libui/common/control.c b/src/libui_sdl/libui/common/control.c
new file mode 100644
index 0000000..2806646
--- /dev/null
+++ b/src/libui_sdl/libui/common/control.c
@@ -0,0 +1,101 @@
+// 26 may 2015
+#include "../ui.h"
+#include "uipriv.h"
+
+void uiControlDestroy(uiControl *c)
+{
+ (*(c->Destroy))(c);
+}
+
+uintptr_t uiControlHandle(uiControl *c)
+{
+ return (*(c->Handle))(c);
+}
+
+uiControl *uiControlParent(uiControl *c)
+{
+ return (*(c->Parent))(c);
+}
+
+void uiControlSetParent(uiControl *c, uiControl *parent)
+{
+ (*(c->SetParent))(c, parent);
+}
+
+int uiControlToplevel(uiControl *c)
+{
+ return (*(c->Toplevel))(c);
+}
+
+int uiControlVisible(uiControl *c)
+{
+ return (*(c->Visible))(c);
+}
+
+void uiControlShow(uiControl *c)
+{
+ (*(c->Show))(c);
+}
+
+void uiControlHide(uiControl *c)
+{
+ (*(c->Hide))(c);
+}
+
+int uiControlEnabled(uiControl *c)
+{
+ return (*(c->Enabled))(c);
+}
+
+void uiControlEnable(uiControl *c)
+{
+ (*(c->Enable))(c);
+}
+
+void uiControlDisable(uiControl *c)
+{
+ (*(c->Disable))(c);
+}
+
+#define uiControlSignature 0x7569436F
+
+uiControl *uiAllocControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr)
+{
+ uiControl *c;
+
+ c = (uiControl *) uiAlloc(size, typenamestr);
+ c->Signature = uiControlSignature;
+ c->OSSignature = OSsig;
+ c->TypeSignature = typesig;
+ return c;
+}
+
+void uiFreeControl(uiControl *c)
+{
+ if (uiControlParent(c) != NULL)
+ userbug("You cannot destroy a uiControl while it still has a parent. (control: %p)", c);
+ uiFree(c);
+}
+
+void uiControlVerifySetParent(uiControl *c, uiControl *parent)
+{
+ uiControl *curParent;
+
+ if (uiControlToplevel(c))
+ userbug("You cannot give a toplevel uiControl a parent. (control: %p)", c);
+ curParent = uiControlParent(c);
+ if (parent != NULL && curParent != NULL)
+ userbug("You cannot give a uiControl a parent while it already has one. (control: %p; current parent: %p; new parent: %p)", c, curParent, parent);
+ if (parent == NULL && curParent == NULL)
+ implbug("attempt to double unparent uiControl %p", c);
+}
+
+int uiControlEnabledToUser(uiControl *c)
+{
+ while (c != NULL) {
+ if (!uiControlEnabled(c))
+ return 0;
+ c = uiControlParent(c);
+ }
+ return 1;
+}
diff --git a/src/libui_sdl/libui/common/controlsigs.h b/src/libui_sdl/libui/common/controlsigs.h
new file mode 100644
index 0000000..1cbf18d
--- /dev/null
+++ b/src/libui_sdl/libui/common/controlsigs.h
@@ -0,0 +1,25 @@
+// 24 april 2016
+
+#define uiAreaSignature 0x41726561
+#define uiBoxSignature 0x426F784C
+#define uiButtonSignature 0x42746F6E
+#define uiCheckboxSignature 0x43686B62
+#define uiColorButtonSignature 0x436F6C42
+#define uiComboboxSignature 0x436F6D62
+#define uiDateTimePickerSignature 0x44545069
+#define uiEditableComboboxSignature 0x45644362
+#define uiEntrySignature 0x456E7472
+#define uiFontButtonSignature 0x466F6E42
+#define uiFormSignature 0x466F726D
+#define uiGridSignature 0x47726964
+#define uiGroupSignature 0x47727062
+#define uiLabelSignature 0x4C61626C
+#define uiMultilineEntrySignature 0x4D6C6E45
+#define uiProgressBarSignature 0x50426172
+#define uiRadioButtonsSignature 0x5264696F
+#define uiSeparatorSignature 0x53657061
+#define uiSliderSignature 0x536C6964
+#define uiSpinboxSignature 0x5370696E
+#define uiTabSignature 0x54616273
+#define uiTableSignature 0x5461626C
+#define uiWindowSignature 0x57696E64
diff --git a/src/libui_sdl/libui/common/debug.c b/src/libui_sdl/libui/common/debug.c
new file mode 100644
index 0000000..97280b4
--- /dev/null
+++ b/src/libui_sdl/libui/common/debug.c
@@ -0,0 +1,21 @@
+// 13 may 2016
+#include "../ui.h"
+#include "uipriv.h"
+
+void _implbug(const char *file, const char *line, const char *func, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ realbug(file, line, func, "POSSIBLE IMPLEMENTATION BUG; CONTACT ANDLABS:\n", format, ap);
+ va_end(ap);
+}
+
+void _userbug(const char *file, const char *line, const char *func, const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ realbug(file, line, func, "You have a bug: ", format, ap);
+ va_end(ap);
+}
diff --git a/src/libui_sdl/libui/common/matrix.c b/src/libui_sdl/libui/common/matrix.c
new file mode 100644
index 0000000..676885d
--- /dev/null
+++ b/src/libui_sdl/libui/common/matrix.c
@@ -0,0 +1,50 @@
+// 11 october 2015
+#include <math.h>
+#include "../ui.h"
+#include "uipriv.h"
+
+void uiDrawMatrixSetIdentity(uiDrawMatrix *m)
+{
+ m->M11 = 1;
+ m->M12 = 0;
+ m->M21 = 0;
+ m->M22 = 1;
+ m->M31 = 0;
+ m->M32 = 0;
+}
+
+// The rest of this file provides basic utilities in case the platform doesn't provide any of its own for these tasks.
+// Keep these as minimal as possible. They should generally not call other fallbacks.
+
+// see https://msdn.microsoft.com/en-us/library/windows/desktop/ff684171%28v=vs.85%29.aspx#skew_transform
+// TODO see if there's a way we can avoid the multiplication
+void fallbackSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount)
+{
+ uiDrawMatrix n;
+
+ uiDrawMatrixSetIdentity(&n);
+ // TODO explain this
+ n.M12 = tan(yamount);
+ n.M21 = tan(xamount);
+ n.M31 = -y * tan(xamount);
+ n.M32 = -x * tan(yamount);
+ uiDrawMatrixMultiply(m, &n);
+}
+
+void scaleCenter(double xCenter, double yCenter, double *x, double *y)
+{
+ *x = xCenter - (*x * xCenter);
+ *y = yCenter - (*y * yCenter);
+}
+
+// the basic algorithm is from cairo
+// but it's the same algorithm as the transform point, just without M31 and M32 taken into account, so let's just do that instead
+void fallbackTransformSize(uiDrawMatrix *m, double *x, double *y)
+{
+ uiDrawMatrix m2;
+
+ m2 = *m;
+ m2.M31 = 0;
+ m2.M32 = 0;
+ uiDrawMatrixTransformPoint(&m2, x, y);
+}
diff --git a/src/libui_sdl/libui/common/shouldquit.c b/src/libui_sdl/libui/common/shouldquit.c
new file mode 100644
index 0000000..4e7aa5c
--- /dev/null
+++ b/src/libui_sdl/libui/common/shouldquit.c
@@ -0,0 +1,22 @@
+// 9 may 2015
+#include "../ui.h"
+#include "uipriv.h"
+
+static int defaultOnShouldQuit(void *data)
+{
+ return 0;
+}
+
+static int (*onShouldQuit)(void *) = defaultOnShouldQuit;
+static void *onShouldQuitData;
+
+void uiOnShouldQuit(int (*f)(void *), void *data)
+{
+ onShouldQuit = f;
+ onShouldQuitData = data;
+}
+
+int shouldQuit(void)
+{
+ return (*onShouldQuit)(onShouldQuitData);
+}
diff --git a/src/libui_sdl/libui/common/uipriv.h b/src/libui_sdl/libui/common/uipriv.h
new file mode 100644
index 0000000..d6b54e8
--- /dev/null
+++ b/src/libui_sdl/libui/common/uipriv.h
@@ -0,0 +1,58 @@
+// 6 april 2015
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdarg.h>
+#include "controlsigs.h"
+
+extern uiInitOptions options;
+
+extern void *uiAlloc(size_t, const char *);
+#define uiNew(T) ((T *) uiAlloc(sizeof (T), #T))
+extern void *uiRealloc(void *, size_t, const char *);
+extern void uiFree(void *);
+
+// ugh, this was only introduced in MSVC 2015...
+#ifdef _MSC_VER
+#define __func__ __FUNCTION__
+#endif
+extern void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap);
+#define _ns2(s) #s
+#define _ns(s) _ns2(s)
+extern void _implbug(const char *file, const char *line, const char *func, const char *format, ...);
+#define implbug(...) _implbug(__FILE__, _ns(__LINE__), __func__, __VA_ARGS__)
+extern void _userbug(const char *file, const char *line, const char *func, const char *format, ...);
+#define userbug(...) _userbug(__FILE__, _ns(__LINE__), __func__, __VA_ARGS__)
+
+// control.c
+extern uiControl *newControl(size_t size, uint32_t OSsig, uint32_t typesig, const char *typenamestr);
+
+// shouldquit.c
+extern int shouldQuit(void);
+
+// areaevents.c
+typedef struct clickCounter clickCounter;
+// you should call Reset() to zero-initialize a new instance
+// it doesn't matter that all the non-count fields are zero: the first click will fail the curButton test straightaway, so it'll return 1 and set the rest of the structure accordingly
+struct clickCounter {
+ int curButton;
+ int rectX0;
+ int rectY0;
+ int rectX1;
+ int rectY1;
+ uintptr_t prevTime;
+ int count;
+};
+int clickCounterClick(clickCounter *c, int button, int x, int y, uintptr_t time, uintptr_t maxTime, int32_t xdist, int32_t ydist);
+extern void clickCounterReset(clickCounter *);
+extern int fromScancode(uintptr_t, uiAreaKeyEvent *);
+
+// matrix.c
+extern void fallbackSkew(uiDrawMatrix *, double, double, double, double);
+extern void scaleCenter(double, double, double *, double *);
+extern void fallbackTransformSize(uiDrawMatrix *, double *, double *);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/src/libui_sdl/libui/common/userbugs.c b/src/libui_sdl/libui/common/userbugs.c
new file mode 100644
index 0000000..0a85874
--- /dev/null
+++ b/src/libui_sdl/libui/common/userbugs.c
@@ -0,0 +1,8 @@
+// 22 may 2016
+#include "../ui.h"
+#include "uipriv.h"
+
+void uiUserBugCannotSetParentOnToplevel(const char *type)
+{
+ userbug("You cannot make a %s a child of another uiControl,", type);
+}