aboutsummaryrefslogtreecommitdiff
path: root/src/libui_sdl/libui/unix
diff options
context:
space:
mode:
Diffstat (limited to 'src/libui_sdl/libui/unix')
-rw-r--r--src/libui_sdl/libui/unix/CMakeLists.txt87
-rw-r--r--src/libui_sdl/libui/unix/alloc.c84
-rw-r--r--src/libui_sdl/libui/unix/area.c853
-rw-r--r--src/libui_sdl/libui/unix/box.c159
-rw-r--r--src/libui_sdl/libui/unix/button.c57
-rw-r--r--src/libui_sdl/libui/unix/cellrendererbutton.c299
-rw-r--r--src/libui_sdl/libui/unix/checkbox.c78
-rw-r--r--src/libui_sdl/libui/unix/child.c120
-rw-r--r--src/libui_sdl/libui/unix/colorbutton.c80
-rw-r--r--src/libui_sdl/libui/unix/combobox.c66
-rw-r--r--src/libui_sdl/libui/unix/control.c14
-rw-r--r--src/libui_sdl/libui/unix/datetimepicker.c599
-rw-r--r--src/libui_sdl/libui/unix/debug.c14
-rw-r--r--src/libui_sdl/libui/unix/draw.c214
-rw-r--r--src/libui_sdl/libui/unix/draw.h21
-rw-r--r--src/libui_sdl/libui/unix/drawmatrix.c115
-rw-r--r--src/libui_sdl/libui/unix/drawpath.c199
-rw-r--r--src/libui_sdl/libui/unix/drawtext.c293
-rw-r--r--src/libui_sdl/libui/unix/editablecombo.c79
-rw-r--r--src/libui_sdl/libui/unix/entry.c97
-rw-r--r--src/libui_sdl/libui/unix/fontbutton.c70
-rw-r--r--src/libui_sdl/libui/unix/form.c159
-rw-r--r--src/libui_sdl/libui/unix/future.c42
-rw-r--r--src/libui_sdl/libui/unix/gl.c251
-rw-r--r--src/libui_sdl/libui/unix/graphemes.c31
-rw-r--r--src/libui_sdl/libui/unix/grid.c141
-rw-r--r--src/libui_sdl/libui/unix/group.c89
-rw-r--r--src/libui_sdl/libui/unix/image.c120
-rw-r--r--src/libui_sdl/libui/unix/label.c36
-rw-r--r--src/libui_sdl/libui/unix/main.c147
-rw-r--r--src/libui_sdl/libui/unix/menu.c432
-rw-r--r--src/libui_sdl/libui/unix/multilineentry.c124
-rw-r--r--src/libui_sdl/libui/unix/progressbar.c71
-rw-r--r--src/libui_sdl/libui/unix/radiobuttons.c121
-rw-r--r--src/libui_sdl/libui/unix/separator.c34
-rw-r--r--src/libui_sdl/libui/unix/slider.c71
-rw-r--r--src/libui_sdl/libui/unix/spinbox.c72
-rw-r--r--src/libui_sdl/libui/unix/stddialogs.c116
-rw-r--r--src/libui_sdl/libui/unix/tab.c97
-rw-r--r--src/libui_sdl/libui/unix/text.c12
-rw-r--r--src/libui_sdl/libui/unix/uipriv_unix.h71
-rw-r--r--src/libui_sdl/libui/unix/util.c10
-rw-r--r--src/libui_sdl/libui/unix/window.c462
43 files changed, 0 insertions, 6307 deletions
diff --git a/src/libui_sdl/libui/unix/CMakeLists.txt b/src/libui_sdl/libui/unix/CMakeLists.txt
deleted file mode 100644
index c69081e..0000000
--- a/src/libui_sdl/libui/unix/CMakeLists.txt
+++ /dev/null
@@ -1,87 +0,0 @@
-# 3 june 2016
-
-find_package(PkgConfig REQUIRED)
-pkg_check_modules(GTK REQUIRED gtk+-3.0)
-
-list(APPEND _LIBUI_SOURCES
- unix/alloc.c
- unix/area.c
- unix/box.c
- unix/button.c
- unix/cellrendererbutton.c
- unix/checkbox.c
- unix/child.c
- unix/colorbutton.c
- unix/combobox.c
- unix/control.c
- unix/datetimepicker.c
- unix/debug.c
- unix/draw.c
- unix/drawmatrix.c
- unix/drawpath.c
- unix/drawtext.c
- unix/editablecombo.c
- unix/entry.c
- unix/fontbutton.c
- unix/form.c
- unix/future.c
- unix/graphemes.c
- unix/grid.c
- unix/group.c
- unix/image.c
- unix/label.c
- unix/main.c
- unix/menu.c
- unix/multilineentry.c
- unix/progressbar.c
- unix/radiobuttons.c
- unix/separator.c
- unix/slider.c
- unix/spinbox.c
- unix/stddialogs.c
- unix/tab.c
- unix/text.c
- unix/util.c
- unix/window.c
- unix/gl.c
-)
-set(_LIBUI_SOURCES ${_LIBUI_SOURCES} PARENT_SCOPE)
-
-list(APPEND _LIBUI_INCLUDEDIRS
- unix
-)
-set(_LIBUI_INCLUDEDIRS _LIBUI_INCLUDEDIRS PARENT_SCOPE)
-
-set(_LIBUINAME libui PARENT_SCOPE)
-if(NOT BUILD_SHARED_LIBS)
- set(_LIBUINAME libui-temporary PARENT_SCOPE)
-endif()
-macro(_handle_static)
- set_target_properties(${_LIBUINAME} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}")
- set(_aname $<TARGET_FILE:${_LIBUINAME}>)
- set(_oname libui-combined.o)
- add_custom_command(
- OUTPUT ${_oname}
- DEPENDS ${_LIBUINAME}
- COMMAND
- ld -r --whole-archive ${_aname} -o ${_oname}
- COMMAND
- objcopy --localize-hidden ${_oname}
- COMMENT "Removing hidden symbols")
- add_library(libui STATIC ${_oname})
- # otherwise cmake won't know which linker to use
- set_target_properties(libui PROPERTIES
- LINKER_LANGUAGE C)
- set(_aname)
- set(_oname)
-endmacro()
-
-# TODO the other variables don't work?
-set(_LIBUI_CFLAGS
- ${GTK_CFLAGS}
-PARENT_SCOPE)
-
-set(_LIBUI_LIBS
- ${GTK_LDFLAGS} m ${CMAKE_DL_LIBS}
-PARENT_SCOPE)
diff --git a/src/libui_sdl/libui/unix/alloc.c b/src/libui_sdl/libui/unix/alloc.c
deleted file mode 100644
index 2561efa..0000000
--- a/src/libui_sdl/libui/unix/alloc.c
+++ /dev/null
@@ -1,84 +0,0 @@
-// 7 april 2015
-#include <string.h>
-#include "uipriv_unix.h"
-
-static GPtrArray *allocations;
-
-#define UINT8(p) ((uint8_t *) (p))
-#define PVOID(p) ((void *) (p))
-#define EXTRA (sizeof (size_t) + sizeof (const char **))
-#define DATA(p) PVOID(UINT8(p) + EXTRA)
-#define BASE(p) PVOID(UINT8(p) - EXTRA)
-#define SIZE(p) ((size_t *) (p))
-#define CCHAR(p) ((const char **) (p))
-#define TYPE(p) CCHAR(UINT8(p) + sizeof (size_t))
-
-void initAlloc(void)
-{
- allocations = g_ptr_array_new();
-}
-
-static void uninitComplain(gpointer ptr, gpointer data)
-{
- char **str = (char **) data;
- char *str2;
-
- if (*str == NULL)
- *str = g_strdup_printf("");
- str2 = g_strdup_printf("%s%p %s\n", *str, ptr, *TYPE(ptr));
- g_free(*str);
- *str = str2;
-}
-
-void uninitAlloc(void)
-{
- char *str = NULL;
-
- if (allocations->len == 0) {
- g_ptr_array_free(allocations, TRUE);
- return;
- }
- g_ptr_array_foreach(allocations, uninitComplain, &str);
- userbug("Some data was leaked; either you left a uiControl lying around or there's a bug in libui itself. Leaked data:\n%s", str);
- g_free(str);
-}
-
-void *uiAlloc(size_t size, const char *type)
-{
- void *out;
-
- out = g_malloc0(EXTRA + size);
- *SIZE(out) = size;
- *TYPE(out) = type;
- g_ptr_array_add(allocations, out);
- return DATA(out);
-}
-
-void *uiRealloc(void *p, size_t new, const char *type)
-{
- void *out;
- size_t *s;
-
- if (p == NULL)
- return uiAlloc(new, type);
- p = BASE(p);
- out = g_realloc(p, EXTRA + new);
- s = SIZE(out);
- if (new <= *s)
- memset(((uint8_t *) DATA(out)) + *s, 0, new - *s);
- *s = new;
- if (g_ptr_array_remove(allocations, p) == FALSE)
- implbug("%p not found in allocations array in uiRealloc()", p);
- g_ptr_array_add(allocations, out);
- return DATA(out);
-}
-
-void uiFree(void *p)
-{
- if (p == NULL)
- implbug("attempt to uiFree(NULL)");
- p = BASE(p);
- g_free(p);
- if (g_ptr_array_remove(allocations, p) == FALSE)
- implbug("%p not found in allocations array in uiFree()", p);
-}
diff --git a/src/libui_sdl/libui/unix/area.c b/src/libui_sdl/libui/unix/area.c
deleted file mode 100644
index 5734b4b..0000000
--- a/src/libui_sdl/libui/unix/area.c
+++ /dev/null
@@ -1,853 +0,0 @@
-// 4 september 2015
-#include "uipriv_unix.h"
-
-extern GThread* gtkthread;
-
-// notes:
-// - G_DECLARE_DERIVABLE/FINAL_INTERFACE() requires glib 2.44 and that's starting with debian stretch (testing) (GTK+ 3.18) and ubuntu 15.04 (GTK+ 3.14) - debian jessie has 2.42 (GTK+ 3.14)
-#define areaWidgetType (areaWidget_get_type())
-#define areaWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), areaWidgetType, areaWidget))
-#define isAreaWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), areaWidgetType))
-#define areaWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), areaWidgetType, areaWidgetClass))
-#define isAreaWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), areaWidget))
-#define getAreaWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), areaWidgetType, areaWidgetClass))
-
-typedef struct areaWidget areaWidget;
-typedef struct areaWidgetClass areaWidgetClass;
-
-struct areaWidget {
- GtkDrawingArea parent_instance;
- uiArea *a;
- // construct-only parameters aare not set until after the init() function has returned
- // we need this particular object available during init(), so put it here instead of in uiArea
- // keep a pointer in uiArea for convenience, though
- clickCounter cc;
-};
-
-struct areaWidgetClass {
- GtkDrawingAreaClass parent_class;
-};
-
-typedef struct uiGLContext uiGLContext;
-
-struct uiArea {
- uiUnixControl c;
- GtkWidget *widget; // either swidget or areaWidget depending on whether it is scrolling
-
- GtkWidget *swidget;
- GtkContainer *scontainer;
- GtkScrolledWindow *sw;
-
- GtkWidget *areaWidget;
- GtkDrawingArea *drawingArea;
- areaWidget *area;
-
- gboolean opengl;
- uiGLContext *glContext;
- unsigned int* req_versions;
-
- int bgR, bgG, bgB;
-
- uiAreaHandler *ah;
-
- gboolean scrolling;
- int scrollWidth;
- int scrollHeight;
-
- // note that this is a pointer; see above
- clickCounter *cc;
-
- // for user window drags
- GdkEventButton *dragevent;
-};
-
-G_DEFINE_TYPE(areaWidget, areaWidget, GTK_TYPE_DRAWING_AREA)
-
-int boub(GtkWidget* w) { return isAreaWidget(w); }
-void baba(GtkWidget* w)
-{
- if (!isAreaWidget(w)) return;
-
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
- if (!a->opengl) return;
-
- GdkGLContext* oldctx = gdk_gl_context_get_current();
- uiGLMakeContextCurrent(a->glContext);
- glFinish();
- gdk_gl_context_make_current(oldctx);
-}
-
-static void areaWidget_init(areaWidget *aw)
-{
- // for events
- gtk_widget_add_events(GTK_WIDGET(aw),
- GDK_POINTER_MOTION_MASK |
- GDK_BUTTON_MOTION_MASK |
- GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK |
- GDK_KEY_PRESS_MASK |
- GDK_KEY_RELEASE_MASK |
- GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK);
-
- gtk_widget_set_can_focus(GTK_WIDGET(aw), TRUE);
-
- clickCounterReset(&(aw->cc));
-}
-
-static void areaWidget_dispose(GObject *obj)
-{
- // remove any draw order that might still be pending
- areaWidget *aw = areaWidget(obj);
- while (g_idle_remove_by_data(aw->a));
-
- G_OBJECT_CLASS(areaWidget_parent_class)->dispose(obj);
-}
-
-static void areaWidget_finalize(GObject *obj)
-{
- G_OBJECT_CLASS(areaWidget_parent_class)->finalize(obj);
-}
-
-static void areaWidget_size_allocate(GtkWidget *w, GtkAllocation *allocation)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
-
- // GtkDrawingArea has a size_allocate() implementation; we need to call it
- // this will call gtk_widget_set_allocation() for us
- GTK_WIDGET_CLASS(areaWidget_parent_class)->size_allocate(w, allocation);
-
- if (!a->scrolling)
- // we must redraw everything on resize because Windows requires it
- gtk_widget_queue_resize(w);
-
- a->ah->Resize(a->ah, a, allocation->width, allocation->height);
-}
-
-static void loadAreaSize(uiArea *a, double *width, double *height)
-{
- GtkAllocation allocation;
-
- *width = 0;
- *height = 0;
- // don't provide size information for scrolling areas
- if (!a->scrolling) {
- gtk_widget_get_allocation(a->areaWidget, &allocation);
- // these are already in drawing space coordinates
- // for drawing, the size of drawing space has the same value as the widget allocation
- // thanks to tristan in irc.gimp.net/#gtk+
- *width = allocation.width;
- *height = allocation.height;
- }
-}
-
-static gboolean areaWidget_draw(GtkWidget *w, cairo_t *cr)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
- uiAreaDrawParams dp;
- double clipX0, clipY0, clipX1, clipY1;
-
- dp.Context = newContext(cr);
-
- loadAreaSize(a, &(dp.AreaWidth), &(dp.AreaHeight));
-
- if (!a->opengl)
- {
- cairo_clip_extents(cr, &clipX0, &clipY0, &clipX1, &clipY1);
- dp.ClipX = clipX0;
- dp.ClipY = clipY0;
- dp.ClipWidth = clipX1 - clipX0;
- dp.ClipHeight = clipY1 - clipY0;
-
- if (a->bgR != -1)
- {
- cairo_set_source_rgb(cr, a->bgR/255.0, a->bgG/255.0, a->bgB/255.0);
- cairo_paint(cr);
- }
-
- // no need to save or restore the graphics state to reset transformations; GTK+ does that for us
- (*(a->ah->Draw))(a->ah, a, &dp);
- }
- else
- {
- areaDrawGL(w, &dp, cr, a->glContext);
- }
-
- freeContext(dp.Context);
- return FALSE;
-}
-
-// to do this properly for scrolling areas, we need to
-// - return the same value for min and nat
-// - call gtk_widget_queue_resize() when the size changes
-// thanks to Company in irc.gimp.net/#gtk+
-static void areaWidget_get_preferred_height(GtkWidget *w, gint *min, gint *nat)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
-
- // always chain up just in case
- GTK_WIDGET_CLASS(areaWidget_parent_class)->get_preferred_height(w, min, nat);
- if (a->scrolling) {
- *min = a->scrollHeight;
- *nat = a->scrollHeight;
- }
-
- // TODO: min size
-}
-
-static void areaWidget_get_preferred_width(GtkWidget *w, gint *min, gint *nat)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
-
- // always chain up just in case
- GTK_WIDGET_CLASS(areaWidget_parent_class)->get_preferred_width(w, min, nat);
- if (a->scrolling) {
- *min = a->scrollWidth;
- *nat = a->scrollWidth;
- }
-}
-
-static guint translateModifiers(guint state, GdkWindow *window)
-{
- GdkModifierType statetype;
-
- // GDK doesn't initialize the modifier flags fully; we have to explicitly tell it to (thanks to Daniel_S and daniels (two different people) in irc.gimp.net/#gtk+)
- statetype = state;
- gdk_keymap_add_virtual_modifiers(
- gdk_keymap_get_for_display(gdk_window_get_display(window)),
- &statetype);
- return statetype;
-}
-
-static uiModifiers toModifiers(guint state)
-{
- uiModifiers m;
-
- m = 0;
- if ((state & GDK_CONTROL_MASK) != 0)
- m |= uiModifierCtrl;
- if ((state & GDK_META_MASK) != 0)
- m |= uiModifierAlt;
- if ((state & GDK_MOD1_MASK) != 0) // GTK+ itself requires this to be Alt (just read through gtkaccelgroup.c)
- m |= uiModifierAlt;
- if ((state & GDK_SHIFT_MASK) != 0)
- m |= uiModifierShift;
- if ((state & GDK_SUPER_MASK) != 0)
- m |= uiModifierSuper;
- return m;
-}
-
-// capture on drag is done automatically on GTK+
-static void finishMouseEvent(uiArea *a, uiAreaMouseEvent *me, guint mb, gdouble x, gdouble y, guint state, GdkWindow *window)
-{
- // on GTK+, mouse buttons 4-7 are for scrolling; if we got here, that's a mistake
- if (mb >= 4 && mb <= 7)
- return;
- // if the button ID >= 8, continue counting from 4, as in the MouseEvent spec
- if (me->Down >= 8)
- me->Down -= 4;
- if (me->Up >= 8)
- me->Up -= 4;
-
- state = translateModifiers(state, window);
- me->Modifiers = toModifiers(state);
-
- // the mb != # checks exclude the Up/Down button from Held
- me->Held1To64 = 0;
- if (mb != 1 && (state & GDK_BUTTON1_MASK) != 0)
- me->Held1To64 |= 1 << 0;
- if (mb != 2 && (state & GDK_BUTTON2_MASK) != 0)
- me->Held1To64 |= 1 << 1;
- if (mb != 3 && (state & GDK_BUTTON3_MASK) != 0)
- me->Held1To64 |= 1 << 2;
- // don't check GDK_BUTTON4_MASK or GDK_BUTTON5_MASK because those are for the scrolling buttons mentioned above
- // GDK expressly does not support any more buttons in the GdkModifierType; see https://git.gnome.org/browse/gtk+/tree/gdk/x11/gdkdevice-xi2.c#n763 (thanks mclasen in irc.gimp.net/#gtk+)
-
- // these are already in drawing space coordinates
- // the size of drawing space has the same value as the widget allocation
- // thanks to tristan in irc.gimp.net/#gtk+
- me->X = x;
- me->Y = y;
-
- loadAreaSize(a, &(me->AreaWidth), &(me->AreaHeight));
-
- (*(a->ah->MouseEvent))(a->ah, a, me);
-}
-
-static gboolean areaWidget_button_press_event(GtkWidget *w, GdkEventButton *e)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
- gint maxTime, maxDistance;
- GtkSettings *settings;
- uiAreaMouseEvent me;
-
- // clicking doesn't automatically transfer keyboard focus; we must do so manually (thanks tristan in irc.gimp.net/#gtk+)
- gtk_widget_grab_focus(w);
-
- // we handle multiple clicks ourselves here, in the same way as we do on Windows
- if (e->type != GDK_BUTTON_PRESS)
- // ignore GDK's generated double-clicks and beyond
- return GDK_EVENT_PROPAGATE;
- settings = gtk_widget_get_settings(w);
- g_object_get(settings,
- "gtk-double-click-time", &maxTime,
- "gtk-double-click-distance", &maxDistance,
- NULL);
- // don't unref settings; it's transfer-none (thanks gregier in irc.gimp.net/#gtk+)
- // e->time is guint32
- // e->x and e->y are floating-point; just make them 32-bit integers
- // maxTime and maxDistance... are gint, which *should* fit, hopefully...
- me.Count = clickCounterClick(a->cc, me.Down,
- e->x, e->y,
- e->time, maxTime,
- maxDistance, maxDistance);
-
- me.Down = e->button;
- me.Up = 0;
-
- // and set things up for window drags
- a->dragevent = e;
- finishMouseEvent(a, &me, e->button, e->x, e->y, e->state, e->window);
- a->dragevent = NULL;
- return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean areaWidget_button_release_event(GtkWidget *w, GdkEventButton *e)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
- uiAreaMouseEvent me;
-
- me.Down = 0;
- me.Up = e->button;
- me.Count = 0;
- finishMouseEvent(a, &me, e->button, e->x, e->y, e->state, e->window);
- return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean areaWidget_motion_notify_event(GtkWidget *w, GdkEventMotion *e)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
- uiAreaMouseEvent me;
-
- me.Down = 0;
- me.Up = 0;
- me.Count = 0;
- finishMouseEvent(a, &me, 0, e->x, e->y, e->state, e->window);
- return GDK_EVENT_PROPAGATE;
-}
-
-// we want switching away from the control to reset the double-click counter, like with WM_ACTIVATE on Windows
-// according to tristan in irc.gimp.net/#gtk+, doing this on both enter-notify-event and leave-notify-event is correct (and it seems to be true in my own tests; plus the events DO get sent when switching programs with the keyboard (just pointing that out))
-static gboolean onCrossing(areaWidget *aw, int left)
-{
- uiArea *a = aw->a;
-
- (*(a->ah->MouseCrossed))(a->ah, a, left);
- clickCounterReset(a->cc);
- return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean areaWidget_enter_notify_event(GtkWidget *w, GdkEventCrossing *e)
-{
- return onCrossing(areaWidget(w), 0);
-}
-
-static gboolean areaWidget_leave_notify_event(GtkWidget *w, GdkEventCrossing *e)
-{
- return onCrossing(areaWidget(w), 1);
-}
-
-// note: there is no equivalent to WM_CAPTURECHANGED on GTK+; there literally is no way to break a grab like that (at least not on X11 and Wayland)
-// even if I invoke the task switcher and switch processes, the mouse grab will still be held until I let go of all buttons
-// therefore, no DragBroken()
-
-// we use GDK_KEY_Print as a sentinel because libui will never support the print screen key; that key belongs to the user
-
-static const struct {
- guint keyval;
- uiExtKey extkey;
-} extKeys[] = {
- { GDK_KEY_Escape, uiExtKeyEscape },
- { GDK_KEY_Insert, uiExtKeyInsert },
- { GDK_KEY_Delete, uiExtKeyDelete },
- { GDK_KEY_Home, uiExtKeyHome },
- { GDK_KEY_End, uiExtKeyEnd },
- { GDK_KEY_Page_Up, uiExtKeyPageUp },
- { GDK_KEY_Page_Down, uiExtKeyPageDown },
- { GDK_KEY_Up, uiExtKeyUp },
- { GDK_KEY_Down, uiExtKeyDown },
- { GDK_KEY_Left, uiExtKeyLeft },
- { GDK_KEY_Right, uiExtKeyRight },
- { GDK_KEY_F1, uiExtKeyF1 },
- { GDK_KEY_F2, uiExtKeyF2 },
- { GDK_KEY_F3, uiExtKeyF3 },
- { GDK_KEY_F4, uiExtKeyF4 },
- { GDK_KEY_F5, uiExtKeyF5 },
- { GDK_KEY_F6, uiExtKeyF6 },
- { GDK_KEY_F7, uiExtKeyF7 },
- { GDK_KEY_F8, uiExtKeyF8 },
- { GDK_KEY_F9, uiExtKeyF9 },
- { GDK_KEY_F10, uiExtKeyF10 },
- { GDK_KEY_F11, uiExtKeyF11 },
- { GDK_KEY_F12, uiExtKeyF12 },
- // numpad numeric keys and . are handled in events.c
- { GDK_KEY_KP_Enter, uiExtKeyNEnter },
- { GDK_KEY_KP_Add, uiExtKeyNAdd },
- { GDK_KEY_KP_Subtract, uiExtKeyNSubtract },
- { GDK_KEY_KP_Multiply, uiExtKeyNMultiply },
- { GDK_KEY_KP_Divide, uiExtKeyNDivide },
- { GDK_KEY_Print, 0 },
-};
-
-static const struct {
- guint keyval;
- uiModifiers mod;
-} modKeys[] = {
- { GDK_KEY_Control_L, uiModifierCtrl },
- { GDK_KEY_Control_R, uiModifierCtrl },
- { GDK_KEY_Alt_L, uiModifierAlt },
- { GDK_KEY_Alt_R, uiModifierAlt },
- { GDK_KEY_Meta_L, uiModifierAlt },
- { GDK_KEY_Meta_R, uiModifierAlt },
- { GDK_KEY_Shift_L, uiModifierShift },
- { GDK_KEY_Shift_R, uiModifierShift },
- { GDK_KEY_Super_L, uiModifierSuper },
- { GDK_KEY_Super_R, uiModifierSuper },
- { GDK_KEY_Print, 0 },
-};
-
-// http://www.comptechdoc.org/os/linux/howlinuxworks/linux_hlkeycodes.html
-int scancode_unix2normal(int scan)
-{
- scan -= 8;
-
- // extended keys get weird scancodes. fix 'em up
- switch (scan)
- {
- case 0x60: return 0x11C;
- case 0x61: return 0x11D;
- case 0x62: return 0x135;
- case 0x63: return 0x137;
- case 0x64: return 0x138;
- case 0x66: return 0x147;
- case 0x67: return 0x148;
- case 0x68: return 0x149;
- case 0x69: return 0x14B;
- case 0x6A: return 0x14D;
- case 0x6B: return 0x14F;
- case 0x6C: return 0x150;
- case 0x6D: return 0x151;
- case 0x6E: return 0x152;
- case 0x6F: return 0x153;
- case 0x77: return 0x45; // PAUSE, this one is weird. check it.
- case 0x7D: return 0x15B; // Windows key
- case 0x7F: return 0x15D; // context menu key
- // TODO: there may be more fancy keys
- default: return scan;
- }
-}
-
-int scancode_normal2unix(int scan)
-{
- // extended keys get weird scancodes. fix 'em up
- switch (scan)
- {
- case 0x11C: return 8+0x60;
- case 0x11D: return 8+0x61;
- case 0x135: return 8+0x62;
- case 0x137: return 8+0x63;
- case 0x138: return 8+0x64;
- case 0x147: return 8+0x66;
- case 0x148: return 8+0x67;
- case 0x149: return 8+0x68;
- case 0x14B: return 8+0x69;
- case 0x14D: return 8+0x6A;
- case 0x14F: return 8+0x6B;
- case 0x150: return 8+0x6C;
- case 0x151: return 8+0x6D;
- case 0x152: return 8+0x6E;
- case 0x153: return 8+0x6F;
- case 0x45: return 8+0x77; // PAUSE, this one is weird. check it.
- case 0x15B: return 8+0x7D; // Windows key
- case 0x15D: return 8+0x7F; // context menu key
- // TODO: there may be more fancy keys
- default: return scan + 8;
- }
-}
-
-static int areaKeyEvent(uiArea *a, int up, GdkEventKey *e)
-{
- uiAreaKeyEvent ke;
- guint state;
- int i;
-
- ke.Key = 0;
- ke.ExtKey = 0;
- ke.Modifier = 0;
-
- state = translateModifiers(e->state, e->window);
- ke.Modifiers = toModifiers(state);
-
- ke.Up = up;
- ke.Repeat = 0; // TODO!!!!!
-
- ke.Scancode = scancode_unix2normal(e->hardware_keycode);
-
-#if 0
- for (i = 0; extKeys[i].keyval != GDK_KEY_Print; i++)
- if (extKeys[i].keyval == e->keyval) {
- ke.ExtKey = extKeys[i].extkey;
- goto keyFound;
- }
-
- for (i = 0; modKeys[i].keyval != GDK_KEY_Print; i++)
- if (modKeys[i].keyval == e->keyval) {
- ke.Modifier = modKeys[i].mod;
- // don't include the modifier in ke.Modifiers
- ke.Modifiers &= ~ke.Modifier;
- goto keyFound;
- }
-
- if (fromScancode(e->hardware_keycode - 8, &ke))
- goto keyFound;
-
- // no supported key found; treat as unhandled
- return 0;
-
-keyFound:
-#endif
- return (*(a->ah->KeyEvent))(a->ah, a, &ke);
-}
-
-static gboolean areaWidget_key_press_event(GtkWidget *w, GdkEventKey *e)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
-
- if (areaKeyEvent(a, 0, e))
- return GDK_EVENT_STOP;
- return GDK_EVENT_PROPAGATE;
-}
-
-static gboolean areaWidget_key_release_event(GtkWidget *w, GdkEventKey *e)
-{
- areaWidget *aw = areaWidget(w);
- uiArea *a = aw->a;
-
- if (areaKeyEvent(a, 1, e))
- return GDK_EVENT_STOP;
- return GDK_EVENT_PROPAGATE;
-}
-
-char* uiKeyName(int scancode)
-{
- scancode = scancode_normal2unix(scancode);
-
- char* ret;
- guint* keyvals; int num;
- GdkKeymap* keymap = gdk_keymap_get_for_display(gdk_display_get_default());
- if (gdk_keymap_get_entries_for_keycode(keymap, scancode, NULL, &keyvals, &num))
- {
- // TODO: pick smarter??
- int keyval = keyvals[0];
-
- g_free(keyvals);
-
- ret = gdk_keyval_name(keyval);
- }
- else
- {
- char tmp[16];
- sprintf(tmp, "#%03X", scancode);
- ret = tmp;
- }
-
- return uiUnixStrdupText(ret);
-}
-
-enum {
- pArea = 1,
- nProps,
-};
-
-static GParamSpec *pspecArea;
-
-static void areaWidget_set_property(GObject *obj, guint prop, const GValue *value, GParamSpec *pspec)
-{
- areaWidget *aw = areaWidget(obj);
-
- switch (prop) {
- case pArea:
- aw->a = (uiArea *) g_value_get_pointer(value);
- aw->a->cc = &(aw->cc);
- return;
- }
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop, pspec);
-}
-
-static void areaWidget_get_property(GObject *obj, guint prop, GValue *value, GParamSpec *pspec)
-{
- G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, prop, pspec);
-}
-
-static void areaWidget_class_init(areaWidgetClass *class)
-{
- G_OBJECT_CLASS(class)->dispose = areaWidget_dispose;
- G_OBJECT_CLASS(class)->finalize = areaWidget_finalize;
- G_OBJECT_CLASS(class)->set_property = areaWidget_set_property;
- G_OBJECT_CLASS(class)->get_property = areaWidget_get_property;
-
- GTK_WIDGET_CLASS(class)->size_allocate = areaWidget_size_allocate;
- GTK_WIDGET_CLASS(class)->draw = areaWidget_draw;
- GTK_WIDGET_CLASS(class)->get_preferred_height = areaWidget_get_preferred_height;
- GTK_WIDGET_CLASS(class)->get_preferred_width = areaWidget_get_preferred_width;
- GTK_WIDGET_CLASS(class)->button_press_event = areaWidget_button_press_event;
- GTK_WIDGET_CLASS(class)->button_release_event = areaWidget_button_release_event;
- GTK_WIDGET_CLASS(class)->motion_notify_event = areaWidget_motion_notify_event;
- GTK_WIDGET_CLASS(class)->enter_notify_event = areaWidget_enter_notify_event;
- GTK_WIDGET_CLASS(class)->leave_notify_event = areaWidget_leave_notify_event;
- GTK_WIDGET_CLASS(class)->key_press_event = areaWidget_key_press_event;
- GTK_WIDGET_CLASS(class)->key_release_event = areaWidget_key_release_event;
-
- pspecArea = g_param_spec_pointer("libui-area",
- "libui-area",
- "uiArea.",
- G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property(G_OBJECT_CLASS(class), pArea, pspecArea);
-}
-
-// control implementation
-
-uiUnixControlAllDefaultsExceptDestroy(uiArea)
-
-static void uiAreaDestroy(uiControl *c)
-{
- uiArea* a = uiArea(c);
- if (a->opengl && a->glContext) freeGLContext(a->glContext);
- g_object_unref(uiArea(c)->widget);
- uiFreeControl(c);
-}
-
-void uiAreaSetBackgroundColor(uiArea *a, int r, int g, int b)
-{
- a->bgR = r;
- a->bgG = g;
- a->bgB = b;
-}
-
-void uiAreaSetSize(uiArea *a, int width, int height)
-{
- if (!a->scrolling)
- userbug("You cannot call uiAreaSetSize() on a non-scrolling uiArea. (area: %p)", a);
- a->scrollWidth = width;
- a->scrollHeight = height;
- gtk_widget_queue_resize(a->areaWidget);
-}
-
-gboolean _threadsaferefresh(gpointer data)
-{
- uiArea* a = (uiArea*)data;
- gtk_widget_queue_draw(a->areaWidget);
- return FALSE;
-}
-
-void uiAreaQueueRedrawAll(uiArea *a)
-{
- // TODO: figure out how we could generalize the "thread-safe function call" mechanism
- if (g_thread_self() != gtkthread)
- g_idle_add(_threadsaferefresh, a);
- else
- gtk_widget_queue_draw(a->areaWidget);
-}
-
-void uiAreaScrollTo(uiArea *a, double x, double y, double width, double height)
-{
- // TODO
- // TODO adjust adjustments and find source for that
-}
-
-void uiAreaBeginUserWindowMove(uiArea *a)
-{
- GtkWidget *toplevel;
-
- if (a->dragevent == NULL)
- userbug("cannot call uiAreaBeginUserWindowMove() outside of a Mouse() with Down != 0");
- // TODO don't we have a libui function for this? did I scrap it?
- // TODO widget or areaWidget?
- toplevel = gtk_widget_get_toplevel(a->widget);
- if (toplevel == NULL) {
- // TODO
- return;
- }
- // the docs say to do this
- if (!gtk_widget_is_toplevel(toplevel)) {
- // TODO
- return;
- }
- if (!GTK_IS_WINDOW(toplevel)) {
- // TODO
- return;
- }
- gtk_window_begin_move_drag(GTK_WINDOW(toplevel),
- a->dragevent->button,
- a->dragevent->x_root, // TODO are these correct?
- a->dragevent->y_root,
- a->dragevent->time);
-}
-
-static const GdkWindowEdge edges[] = {
- [uiWindowResizeEdgeLeft] = GDK_WINDOW_EDGE_WEST,
- [uiWindowResizeEdgeTop] = GDK_WINDOW_EDGE_NORTH,
- [uiWindowResizeEdgeRight] = GDK_WINDOW_EDGE_EAST,
- [uiWindowResizeEdgeBottom] = GDK_WINDOW_EDGE_SOUTH,
- [uiWindowResizeEdgeTopLeft] = GDK_WINDOW_EDGE_NORTH_WEST,
- [uiWindowResizeEdgeTopRight] = GDK_WINDOW_EDGE_NORTH_EAST,
- [uiWindowResizeEdgeBottomLeft] = GDK_WINDOW_EDGE_SOUTH_WEST,
- [uiWindowResizeEdgeBottomRight] = GDK_WINDOW_EDGE_SOUTH_EAST,
-};
-
-void uiAreaBeginUserWindowResize(uiArea *a, uiWindowResizeEdge edge)
-{
- GtkWidget *toplevel;
-
- if (a->dragevent == NULL)
- userbug("cannot call uiAreaBeginUserWindowResize() outside of a Mouse() with Down != 0");
- // TODO don't we have a libui function for this? did I scrap it?
- // TODO widget or areaWidget?
- toplevel = gtk_widget_get_toplevel(a->widget);
- if (toplevel == NULL) {
- // TODO
- return;
- }
- // the docs say to do this
- if (!gtk_widget_is_toplevel(toplevel)) {
- // TODO
- return;
- }
- if (!GTK_IS_WINDOW(toplevel)) {
- // TODO
- return;
- }
- gtk_window_begin_resize_drag(GTK_WINDOW(toplevel),
- edges[edge],
- a->dragevent->button,
- a->dragevent->x_root, // TODO are these correct?
- a->dragevent->y_root,
- a->dragevent->time);
-}
-
-uiArea *uiNewArea(uiAreaHandler *ah)
-{
- uiArea *a;
-
- uiUnixNewControl(uiArea, a);
-
- a->ah = ah;
- a->scrolling = FALSE;
- a->opengl = FALSE;
-
- a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType,
- "libui-area", a,
- NULL));
- a->drawingArea = GTK_DRAWING_AREA(a->areaWidget);
- a->area = areaWidget(a->areaWidget);
-
- a->widget = a->areaWidget;
-
- uiAreaSetBackgroundColor(a, -1, -1, -1);
-
- return a;
-}
-
-void _areaCreateGLContext(GtkWidget* widget, gpointer data)
-{
- uiArea* a = (uiArea*)data;
-
- uiGLContext* ctx = NULL;
- for (int i = 0; a->req_versions[i] && !ctx; i++)
- {
- int major = uiGLVerMajor(a->req_versions[i]);
- int minor = uiGLVerMinor(a->req_versions[i]);
-
- // we cannot support any version older than 3.2 via GDK
- if ((major < 3) || (major == 3 && minor < 2))
- break;
-
- ctx = createGLContext(widget, major, minor);
- }
-
- a->glContext = ctx;
-}
-
-uiArea *uiNewGLArea(uiAreaHandler *ah, const unsigned int* req_versions)
-{
- uiArea *a;
-
- uiUnixNewControl(uiArea, a);
-
- a->ah = ah;
- a->scrolling = FALSE;
- a->opengl = TRUE;
-
- a->glContext = NULL;
- a->req_versions = req_versions;
- a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType,
- "libui-area", a,
- NULL));
- a->area = areaWidget(a->areaWidget);
-
- a->widget = a->areaWidget;
-
- g_signal_connect(a->widget, "realize", G_CALLBACK(_areaCreateGLContext), a);
-
- uiAreaSetBackgroundColor(a, -1, -1, -1);
-
- return a;
-}
-
-uiGLContext *uiAreaGetGLContext(uiArea* a)
-{
- if (!a) return NULL;
- return a->glContext;
-}
-
-uiArea *uiNewScrollingArea(uiAreaHandler *ah, int width, int height)
-{
- uiArea *a;
-
- uiUnixNewControl(uiArea, a);
-
- a->ah = ah;
- a->scrolling = TRUE;
- a->scrollWidth = width;
- a->scrollHeight = height;
- a->opengl = FALSE;
-
- a->swidget = gtk_scrolled_window_new(NULL, NULL);
- a->scontainer = GTK_CONTAINER(a->swidget);
- a->sw = GTK_SCROLLED_WINDOW(a->swidget);
-
- a->areaWidget = GTK_WIDGET(g_object_new(areaWidgetType,
- "libui-area", a,
- NULL));
- a->drawingArea = GTK_DRAWING_AREA(a->areaWidget);
- a->area = areaWidget(a->areaWidget);
-
- a->widget = a->swidget;
-
- uiAreaSetBackgroundColor(a, -1, -1, -1);
-
- gtk_container_add(a->scontainer, a->areaWidget);
- // and make the area visible; only the scrolled window's visibility is controlled by libui
- gtk_widget_show(a->areaWidget);
-
- return a;
-}
diff --git a/src/libui_sdl/libui/unix/box.c b/src/libui_sdl/libui/unix/box.c
deleted file mode 100644
index 23fb7f7..0000000
--- a/src/libui_sdl/libui/unix/box.c
+++ /dev/null
@@ -1,159 +0,0 @@
-// 7 april 2015
-#include "uipriv_unix.h"
-
-struct boxChild {
- uiControl *c;
- int stretchy;
- gboolean oldhexpand;
- GtkAlign oldhalign;
- gboolean oldvexpand;
- GtkAlign oldvalign;
-};
-
-struct uiBox {
- uiUnixControl c;
- GtkWidget *widget;
- GtkContainer *container;
- GtkBox *box;
- GArray *controls;
- int vertical;
- int padded;
- GtkSizeGroup *stretchygroup; // ensures all stretchy controls have the same size
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiBox)
-
-#define ctrl(b, i) &g_array_index(b->controls, struct boxChild, i)
-
-static void uiBoxDestroy(uiControl *c)
-{
- uiBox *b = uiBox(c);
- struct boxChild *bc;
- guint i;
-
- // kill the size group
- g_object_unref(b->stretchygroup);
- // free all controls
- for (i = 0; i < b->controls->len; i++) {
- bc = ctrl(b, i);
- uiControlSetParent(bc->c, NULL);
- // and make sure the widget itself stays alive
- uiUnixControlSetContainer(uiUnixControl(bc->c), b->container, TRUE);
- uiControlDestroy(bc->c);
- }
- g_array_free(b->controls, TRUE);
- // and then ourselves
- g_object_unref(b->widget);
- uiFreeControl(uiControl(b));
-}
-
-void uiBoxAppend(uiBox *b, uiControl *c, int stretchy)
-{
- struct boxChild bc;
- GtkWidget *widget;
-
- bc.c = c;
- bc.stretchy = stretchy;
- widget = GTK_WIDGET(uiControlHandle(bc.c));
- bc.oldhexpand = gtk_widget_get_hexpand(widget);
- bc.oldhalign = gtk_widget_get_halign(widget);
- bc.oldvexpand = gtk_widget_get_vexpand(widget);
- bc.oldvalign = gtk_widget_get_valign(widget);
-
- if (bc.stretchy) {
- if (b->vertical) {
- gtk_widget_set_vexpand(widget, TRUE);
- gtk_widget_set_valign(widget, GTK_ALIGN_FILL);
- } else {
- gtk_widget_set_hexpand(widget, TRUE);
- gtk_widget_set_halign(widget, GTK_ALIGN_FILL);
- }
- gtk_size_group_add_widget(b->stretchygroup, widget);
- } else
- if (b->vertical)
- gtk_widget_set_vexpand(widget, FALSE);
- else
- gtk_widget_set_hexpand(widget, FALSE);
- // and make them fill the opposite direction
- if (b->vertical) {
- gtk_widget_set_hexpand(widget, TRUE);
- gtk_widget_set_halign(widget, GTK_ALIGN_FILL);
- } else {
- gtk_widget_set_vexpand(widget, TRUE);
- gtk_widget_set_valign(widget, GTK_ALIGN_FILL);
- }
-
- uiControlSetParent(bc.c, uiControl(b));
- uiUnixControlSetContainer(uiUnixControl(bc.c), b->container, FALSE);
- g_array_append_val(b->controls, bc);
-}
-
-void uiBoxDelete(uiBox *b, int index)
-{
- struct boxChild *bc;
- GtkWidget *widget;
-
- bc = ctrl(b, index);
- widget = GTK_WIDGET(uiControlHandle(bc->c));
-
- uiControlSetParent(bc->c, NULL);
- uiUnixControlSetContainer(uiUnixControl(bc->c), b->container, TRUE);
-
- if (bc->stretchy)
- gtk_size_group_remove_widget(b->stretchygroup, widget);
- gtk_widget_set_hexpand(widget, bc->oldhexpand);
- gtk_widget_set_halign(widget, bc->oldhalign);
- gtk_widget_set_vexpand(widget, bc->oldvexpand);
- gtk_widget_set_valign(widget, bc->oldvalign);
-
- g_array_remove_index(b->controls, index);
-}
-
-int uiBoxPadded(uiBox *b)
-{
- return b->padded;
-}
-
-void uiBoxSetPadded(uiBox *b, int padded)
-{
- b->padded = padded;
- if (b->padded)
- if (b->vertical)
- gtk_box_set_spacing(b->box, gtkYPadding);
- else
- gtk_box_set_spacing(b->box, gtkXPadding);
- else
- gtk_box_set_spacing(b->box, 0);
-}
-
-static uiBox *finishNewBox(GtkOrientation orientation)
-{
- uiBox *b;
-
- uiUnixNewControl(uiBox, b);
-
- b->widget = gtk_box_new(orientation, 0);
- b->container = GTK_CONTAINER(b->widget);
- b->box = GTK_BOX(b->widget);
-
- b->vertical = orientation == GTK_ORIENTATION_VERTICAL;
-
- if (b->vertical)
- b->stretchygroup = gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL);
- else
- b->stretchygroup = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
-
- b->controls = g_array_new(FALSE, TRUE, sizeof (struct boxChild));
-
- return b;
-}
-
-uiBox *uiNewHorizontalBox(void)
-{
- return finishNewBox(GTK_ORIENTATION_HORIZONTAL);
-}
-
-uiBox *uiNewVerticalBox(void)
-{
- return finishNewBox(GTK_ORIENTATION_VERTICAL);
-}
diff --git a/src/libui_sdl/libui/unix/button.c b/src/libui_sdl/libui/unix/button.c
deleted file mode 100644
index b0500e3..0000000
--- a/src/libui_sdl/libui/unix/button.c
+++ /dev/null
@@ -1,57 +0,0 @@
-// 10 june 2015
-#include "uipriv_unix.h"
-
-struct uiButton {
- uiUnixControl c;
- GtkWidget *widget;
- GtkButton *button;
- void (*onClicked)(uiButton *, void *);
- void *onClickedData;
-};
-
-uiUnixControlAllDefaults(uiButton)
-
-static void onClicked(GtkButton *button, gpointer data)
-{
- uiButton *b = uiButton(data);
-
- (*(b->onClicked))(b, b->onClickedData);
-}
-
-static void defaultOnClicked(uiButton *b, void *data)
-{
- // do nothing
-}
-
-char *uiButtonText(uiButton *b)
-{
- return uiUnixStrdupText(gtk_button_get_label(b->button));
-}
-
-void uiButtonSetText(uiButton *b, const char *text)
-{
- gtk_button_set_label(b->button, text);
-}
-
-void uiButtonOnClicked(uiButton *b, void (*f)(uiButton *, void *), void *data)
-{
- b->onClicked = f;
- b->onClickedData = data;
-}
-
-uiButton *uiNewButton(const char *text)
-{
- uiButton *b;
-
- uiUnixNewControl(uiButton, b);
-
- b->widget = gtk_button_new_with_label(text);
- b->button = GTK_BUTTON(b->widget);
-
- g_signal_connect(b->widget, "clicked", G_CALLBACK(onClicked), b);
- uiButtonOnClicked(b, defaultOnClicked, NULL);
-
- gtk_widget_set_size_request(b->widget, 64, 1);
-
- return b;
-}
diff --git a/src/libui_sdl/libui/unix/cellrendererbutton.c b/src/libui_sdl/libui/unix/cellrendererbutton.c
deleted file mode 100644
index e3bbf48..0000000
--- a/src/libui_sdl/libui/unix/cellrendererbutton.c
+++ /dev/null
@@ -1,299 +0,0 @@
-// 28 june 2016
-#include "uipriv_unix.h"
-
-// TODOs
-// - it's a rather tight fit
-// - selected row text color is white
-// - resizing a column with a button in it crashes the program
-// - accessibility
-// - right side too big?
-
-#define cellRendererButtonType (cellRendererButton_get_type())
-#define cellRendererButton(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), cellRendererButtonType, cellRendererButton))
-#define isCellRendererButton(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), cellRendererButtonType))
-#define cellRendererButtonClass(class) (G_TYPE_CHECK_CLASS_CAST((class), cellRendererButtonType, cellRendererButtonClass))
-#define isCellRendererButtonClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), cellRendererButton))
-#define getCellRendererButtonClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), cellRendererButtonType, cellRendererButtonClass))
-
-typedef struct cellRendererButton cellRendererButton;
-typedef struct cellRendererButtonClass cellRendererButtonClass;
-
-struct cellRendererButton {
- GtkCellRenderer parent_instance;
- char *text;
-};
-
-struct cellRendererButtonClass {
- GtkCellRendererClass parent_class;
-};
-
-G_DEFINE_TYPE(cellRendererButton, cellRendererButton, GTK_TYPE_CELL_RENDERER)
-
-static void cellRendererButton_init(cellRendererButton *c)
-{
- g_object_set(c, "mode", GTK_CELL_RENDERER_MODE_ACTIVATABLE, NULL);
- // the standard cell renderers all do this
- gtk_cell_renderer_set_padding(GTK_CELL_RENDERER(c), 2, 2);
-}
-
-static void cellRendererButton_dispose(GObject *obj)
-{
- G_OBJECT_CLASS(cellRendererButton_parent_class)->dispose(obj);
-}
-
-static void cellRendererButton_finalize(GObject *obj)
-{
- cellRendererButton *c = cellRendererButton(obj);
-
- if (c->text != NULL) {
- g_free(c->text);
- c->text = NULL;
- }
- G_OBJECT_CLASS(cellRendererButton_parent_class)->finalize(obj);
-}
-
-static GtkSizeRequestMode cellRendererButton_get_request_mode(GtkCellRenderer *r)
-{
- return GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH;
-}
-
-// this is basically what GtkCellRendererToggle did in 3.10 and does in 3.20, as well as what the Foreign Drawing gtk3-demo demo does
-static GtkStyleContext *setButtonStyle(GtkWidget *widget)
-{
- GtkStyleContext *base, *context;
- GtkWidgetPath *path;
-
- base = gtk_widget_get_style_context(widget);
- context = gtk_style_context_new();
-
- path = gtk_widget_path_copy(gtk_style_context_get_path(base));
- gtk_widget_path_append_type(path, G_TYPE_NONE);
- if (!FUTURE_gtk_widget_path_iter_set_object_name(path, -1, "button"))
- // not on 3.20; try the type
- gtk_widget_path_iter_set_object_type(path, -1, GTK_TYPE_BUTTON);
-
- gtk_style_context_set_path(context, path);
- gtk_style_context_set_parent(context, base);
- // the gtk3-demo example (which says we need to do this) uses gtk_widget_path_iter_get_state(path, -1) but that's not available until 3.14
- // TODO make a future for that too
- gtk_style_context_set_state(context, gtk_style_context_get_state(base));
- gtk_widget_path_unref(path);
-
- // and if the above widget path screwery stil doesn't work, this will
- gtk_style_context_add_class(context, GTK_STYLE_CLASS_BUTTON);
-
- return context;
-}
-
-void unsetButtonStyle(GtkStyleContext *context)
-{
- g_object_unref(context);
-}
-
-// this is based on what GtkCellRendererText does
-static void cellRendererButton_get_preferred_width(GtkCellRenderer *r, GtkWidget *widget, gint *minimum, gint *natural)
-{
- cellRendererButton *c = cellRendererButton(r);
- gint xpad;
- PangoLayout *layout;
- PangoRectangle rect;
- gint out;
-
- gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, NULL);
-
- layout = gtk_widget_create_pango_layout(widget, c->text);
- pango_layout_set_width(layout, -1);
- pango_layout_get_extents(layout, NULL, &rect);
- g_object_unref(layout);
-
- out = 2 * xpad + PANGO_PIXELS_CEIL(rect.width);
- if (minimum != NULL)
- *minimum = out;
- if (natural != NULL)
- *natural = out;
-}
-
-// this is based on what GtkCellRendererText does
-static void cellRendererButton_get_preferred_height_for_width(GtkCellRenderer *r, GtkWidget *widget, gint width, gint *minimum, gint *natural)
-{
- cellRendererButton *c = cellRendererButton(r);
- gint xpad, ypad;
- PangoLayout *layout;
- gint height;
- gint out;
-
- gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, &ypad);
-
- layout = gtk_widget_create_pango_layout(widget, c->text);
- pango_layout_set_width(layout, ((2 * xpad + width) * PANGO_SCALE));
- pango_layout_get_pixel_size(layout, NULL, &height);
- g_object_unref(layout);
-
- out = 2 * ypad + height;
- if (minimum != NULL)
- *minimum = out;
- if (natural != NULL)
- *natural = out;
-}
-
-// this is basically what GtkCellRendererText does
-static void cellRendererButton_get_preferred_height(GtkCellRenderer *r, GtkWidget *widget, gint *minimum, gint *natural)
-{
- gint width;
-
- gtk_cell_renderer_get_preferred_width(r, widget, &width, NULL);
- gtk_cell_renderer_get_preferred_height_for_width(r, widget, width, minimum, natural);
-}
-
-// this is based on what GtkCellRendererText does
-static void cellRendererButton_get_aligned_area(GtkCellRenderer *r, GtkWidget *widget, GtkCellRendererState flags, const GdkRectangle *cell_area, GdkRectangle *aligned_area)
-{
- cellRendererButton *c = cellRendererButton(r);
- gint xpad, ypad;
- PangoLayout *layout;
- PangoRectangle rect;
- gfloat xalign, yalign;
- gint xoffset, yoffset;
-
- gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, &ypad);
-
- layout = gtk_widget_create_pango_layout(widget, c->text);
- pango_layout_set_width(layout, -1);
- pango_layout_get_pixel_extents(layout, NULL, &rect);
-
- xoffset = 0;
- yoffset = 0;
- if (cell_area != NULL) {
- gtk_cell_renderer_get_alignment(GTK_CELL_RENDERER(c), &xalign, &yalign);
- xoffset = cell_area->width - (2 * xpad + rect.width);
- // use explicit casts just to be safe
- if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_RTL)
- xoffset = ((gdouble) xoffset) * (1.0 - xalign);
- else
- xoffset *= ((gdouble) xoffset) * xalign;
- yoffset = yalign * (cell_area->height - (2 * ypad + rect.height));
- yoffset = MAX(yoffset, 0);
- }
-
- aligned_area->x = cell_area->x + xoffset;
- aligned_area->y = cell_area->y + yoffset;
- aligned_area->width = 2 * xpad + rect.width;
- aligned_area->height = 2 * ypad + rect.height;
-
- g_object_unref(layout);
-}
-
-// this is based on both what GtkCellRendererText does and what GtkCellRendererToggle does
-static void cellRendererButton_render(GtkCellRenderer *r, cairo_t *cr, GtkWidget *widget, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags)
-{
- cellRendererButton *c = cellRendererButton(r);
- gint xpad, ypad;
- GdkRectangle alignedArea;
- gint xoffset, yoffset;
- GtkStyleContext *context;
- PangoLayout *layout;
- PangoRectangle rect;
-
- gtk_cell_renderer_get_padding(GTK_CELL_RENDERER(c), &xpad, &ypad);
- gtk_cell_renderer_get_aligned_area(GTK_CELL_RENDERER(c), widget, flags, cell_area, &alignedArea);
- xoffset = alignedArea.x - cell_area->x;
- yoffset = alignedArea.y - cell_area->y;
-
- context = setButtonStyle(widget);
- layout = gtk_widget_create_pango_layout(widget, c->text);
-
- gtk_render_background(context, cr,
- background_area->x + xoffset + xpad,
- background_area->y + yoffset + ypad,
- background_area->width - 2 * xpad,
- background_area->height - 2 * ypad);
- gtk_render_frame(context, cr,
- background_area->x + xoffset + xpad,
- background_area->y + yoffset + ypad,
- background_area->width - 2 * xpad,
- background_area->height - 2 * ypad);
-
- pango_layout_set_width(layout, -1);
- pango_layout_get_pixel_extents(layout, NULL, &rect);
- xoffset -= rect.x;
- gtk_render_layout(context, cr,
- cell_area->x + xoffset + xpad,
- cell_area->y + yoffset + ypad,
- layout);
-
- g_object_unref(layout);
- unsetButtonStyle(context);
-}
-
-static guint clickedSignal;
-
-static gboolean cellRendererButton_activate(GtkCellRenderer *r, GdkEvent *e, GtkWidget *widget, const gchar *path, const GdkRectangle *background_area, const GdkRectangle *cell_area, GtkCellRendererState flags)
-{
- g_signal_emit(r, clickedSignal, 0, path);
- return TRUE;
-}
-
-static GParamSpec *props[2] = { NULL, NULL };
-
-static void cellRendererButton_set_property(GObject *object, guint prop, const GValue *value, GParamSpec *pspec)
-{
- cellRendererButton *c = cellRendererButton(object);
-
- if (prop != 1) {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(c, prop, pspec);
- return;
- }
- if (c->text != NULL)
- g_free(c->text);
- c->text = g_value_dup_string(value);
- // GtkCellRendererText doesn't queue a redraw; we won't either
-}
-
-static void cellRendererButton_get_property(GObject *object, guint prop, GValue *value, GParamSpec *pspec)
-{
- cellRendererButton *c = cellRendererButton(object);
-
- if (prop != 1) {
- G_OBJECT_WARN_INVALID_PROPERTY_ID(c, prop, pspec);
- return;
- }
- g_value_set_string(value, c->text);
-}
-
-static void cellRendererButton_class_init(cellRendererButtonClass *class)
-{
- G_OBJECT_CLASS(class)->dispose = cellRendererButton_dispose;
- G_OBJECT_CLASS(class)->finalize = cellRendererButton_finalize;
- G_OBJECT_CLASS(class)->set_property = cellRendererButton_set_property;
- G_OBJECT_CLASS(class)->get_property = cellRendererButton_get_property;
- GTK_CELL_RENDERER_CLASS(class)->get_request_mode = cellRendererButton_get_request_mode;
- GTK_CELL_RENDERER_CLASS(class)->get_preferred_width = cellRendererButton_get_preferred_width;
- GTK_CELL_RENDERER_CLASS(class)->get_preferred_height_for_width = cellRendererButton_get_preferred_height_for_width;
- GTK_CELL_RENDERER_CLASS(class)->get_preferred_height = cellRendererButton_get_preferred_height;
- // don't provide a get_preferred_width_for_height()
- GTK_CELL_RENDERER_CLASS(class)->get_aligned_area = cellRendererButton_get_aligned_area;
- // don't provide a get_size()
- GTK_CELL_RENDERER_CLASS(class)->render = cellRendererButton_render;
- GTK_CELL_RENDERER_CLASS(class)->activate = cellRendererButton_activate;
- // don't provide a start_editing()
-
- props[1] = g_param_spec_string("text",
- "Text",
- "Button text",
- "",
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
- g_object_class_install_properties(G_OBJECT_CLASS(class), 2, props);
-
- clickedSignal = g_signal_new("clicked",
- G_TYPE_FROM_CLASS(class),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL, NULL,
- G_TYPE_NONE,
- 1, G_TYPE_STRING);
-}
-
-GtkCellRenderer *newCellRendererButton(void)
-{
- return GTK_CELL_RENDERER(g_object_new(cellRendererButtonType, NULL));
-}
diff --git a/src/libui_sdl/libui/unix/checkbox.c b/src/libui_sdl/libui/unix/checkbox.c
deleted file mode 100644
index 47f8514..0000000
--- a/src/libui_sdl/libui/unix/checkbox.c
+++ /dev/null
@@ -1,78 +0,0 @@
-// 10 june 2015
-#include "uipriv_unix.h"
-
-struct uiCheckbox {
- uiUnixControl c;
- GtkWidget *widget;
- GtkButton *button;
- GtkToggleButton *toggleButton;
- GtkCheckButton *checkButton;
- void (*onToggled)(uiCheckbox *, void *);
- void *onToggledData;
- gulong onToggledSignal;
-};
-
-uiUnixControlAllDefaults(uiCheckbox)
-
-static void onToggled(GtkToggleButton *b, gpointer data)
-{
- uiCheckbox *c = uiCheckbox(data);
-
- (*(c->onToggled))(c, c->onToggledData);
-}
-
-static void defaultOnToggled(uiCheckbox *c, void *data)
-{
- // do nothing
-}
-
-char *uiCheckboxText(uiCheckbox *c)
-{
- return uiUnixStrdupText(gtk_button_get_label(c->button));
-}
-
-void uiCheckboxSetText(uiCheckbox *c, const char *text)
-{
- gtk_button_set_label(GTK_BUTTON(c->button), text);
-}
-
-void uiCheckboxOnToggled(uiCheckbox *c, void (*f)(uiCheckbox *, void *), void *data)
-{
- c->onToggled = f;
- c->onToggledData = data;
-}
-
-int uiCheckboxChecked(uiCheckbox *c)
-{
- return gtk_toggle_button_get_active(c->toggleButton) != FALSE;
-}
-
-void uiCheckboxSetChecked(uiCheckbox *c, int checked)
-{
- gboolean active;
-
- active = FALSE;
- if (checked)
- active = TRUE;
- // we need to inhibit sending of ::toggled because this WILL send a ::toggled otherwise
- g_signal_handler_block(c->toggleButton, c->onToggledSignal);
- gtk_toggle_button_set_active(c->toggleButton, active);
- g_signal_handler_unblock(c->toggleButton, c->onToggledSignal);
-}
-
-uiCheckbox *uiNewCheckbox(const char *text)
-{
- uiCheckbox *c;
-
- uiUnixNewControl(uiCheckbox, c);
-
- c->widget = gtk_check_button_new_with_label(text);
- c->button = GTK_BUTTON(c->widget);
- c->toggleButton = GTK_TOGGLE_BUTTON(c->widget);
- c->checkButton = GTK_CHECK_BUTTON(c->widget);
-
- c->onToggledSignal = g_signal_connect(c->widget, "toggled", G_CALLBACK(onToggled), c);
- uiCheckboxOnToggled(c, defaultOnToggled, NULL);
-
- return c;
-}
diff --git a/src/libui_sdl/libui/unix/child.c b/src/libui_sdl/libui/unix/child.c
deleted file mode 100644
index b4a0967..0000000
--- a/src/libui_sdl/libui/unix/child.c
+++ /dev/null
@@ -1,120 +0,0 @@
-// 28 august 2015
-#include "uipriv_unix.h"
-
-// This file contains helpers for managing child controls.
-
-struct child {
- uiControl *c;
- GtkWidget *widget;
-
- gboolean oldhexpand;
- GtkAlign oldhalign;
- gboolean oldvexpand;
- GtkAlign oldvalign;
-
- // Some children can be boxed; that is, they can have an optionally-margined box around them.
- // uiGroup, uiTab, and uiWindow all do this.
- GtkWidget *box;
-
- // If the child is not boxed, this is its parent.
- // If the child is boxed, this is the box.
- GtkContainer *parent;
-
- // This flag is for users of these functions.
- // For uiBox, this is "spaced".
- // For uiTab, this is "margined". (uiGroup and uiWindow have to maintain their margined state themselves, since the margined state is independent of whether there is a child for those two.)
- int flag;
-};
-
-struct child *newChild(uiControl *child, uiControl *parent, GtkContainer *parentContainer)
-{
- struct child *c;
-
- if (child == NULL)
- return NULL;
-
- c = uiNew(struct child);
- c->c = child;
- c->widget = GTK_WIDGET(uiControlHandle(c->c));
-
- c->oldhexpand = gtk_widget_get_hexpand(c->widget);
- c->oldhalign = gtk_widget_get_halign(c->widget);
- c->oldvexpand = gtk_widget_get_vexpand(c->widget);
- c->oldvalign = gtk_widget_get_valign(c->widget);
-
- uiControlSetParent(c->c, parent);
- uiUnixControlSetContainer(uiUnixControl(c->c), parentContainer, FALSE);
- c->parent = parentContainer;
-
- return c;
-}
-
-struct child *newChildWithBox(uiControl *child, uiControl *parent, GtkContainer *parentContainer, int margined)
-{
- struct child *c;
- GtkWidget *box;
-
- if (child == NULL)
- return NULL;
- box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- gtk_widget_show(box);
- c = newChild(child, parent, GTK_CONTAINER(box));
- gtk_widget_set_hexpand(c->widget, TRUE);
- gtk_widget_set_halign(c->widget, GTK_ALIGN_FILL);
- gtk_widget_set_vexpand(c->widget, TRUE);
- gtk_widget_set_valign(c->widget, GTK_ALIGN_FILL);
- c->box = box;
- gtk_container_add(parentContainer, c->box);
- childSetMargined(c, margined);
- return c;
-}
-
-void childRemove(struct child *c)
-{
- uiControlSetParent(c->c, NULL);
- uiUnixControlSetContainer(uiUnixControl(c->c), c->parent, TRUE);
-
- gtk_widget_set_hexpand(c->widget, c->oldhexpand);
- gtk_widget_set_halign(c->widget, c->oldhalign);
- gtk_widget_set_vexpand(c->widget, c->oldvexpand);
- gtk_widget_set_valign(c->widget, c->oldvalign);
-
- if (c->box != NULL)
- gtk_widget_destroy(c->box);
-
- uiFree(c);
-}
-
-void childDestroy(struct child *c)
-{
- uiControl *child;
-
- child = c->c;
- childRemove(c);
- uiControlDestroy(child);
-}
-
-GtkWidget *childWidget(struct child *c)
-{
- return c->widget;
-}
-
-int childFlag(struct child *c)
-{
- return c->flag;
-}
-
-void childSetFlag(struct child *c, int flag)
-{
- c->flag = flag;
-}
-
-GtkWidget *childBox(struct child *c)
-{
- return c->box;
-}
-
-void childSetMargined(struct child *c, int margined)
-{
- setMargined(GTK_CONTAINER(c->box), margined);
-}
diff --git a/src/libui_sdl/libui/unix/colorbutton.c b/src/libui_sdl/libui/unix/colorbutton.c
deleted file mode 100644
index 393b16f..0000000
--- a/src/libui_sdl/libui/unix/colorbutton.c
+++ /dev/null
@@ -1,80 +0,0 @@
-// 15 may 2016
-#include "uipriv_unix.h"
-
-struct uiColorButton {
- uiUnixControl c;
- GtkWidget *widget;
- GtkButton *button;
- GtkColorButton *cb;
- GtkColorChooser *cc;
- void (*onChanged)(uiColorButton *, void *);
- void *onChangedData;
-};
-
-uiUnixControlAllDefaults(uiColorButton)
-
-static void onColorSet(GtkColorButton *button, gpointer data)
-{
- uiColorButton *b = uiColorButton(data);
-
- (*(b->onChanged))(b, b->onChangedData);
-}
-
-static void defaultOnChanged(uiColorButton *b, void *data)
-{
- // do nothing
-}
-
-void uiColorButtonColor(uiColorButton *b, double *r, double *g, double *bl, double *a)
-{
- GdkRGBA rgba;
-
- gtk_color_chooser_get_rgba(b->cc, &rgba);
- *r = rgba.red;
- *g = rgba.green;
- *bl = rgba.blue;
- *a = rgba.alpha;
-}
-
-void uiColorButtonSetColor(uiColorButton *b, double r, double g, double bl, double a)
-{
- GdkRGBA rgba;
-
- rgba.red = r;
- rgba.green = g;
- rgba.blue = bl;
- rgba.alpha = a;
- // no need to inhibit the signal; color-set is documented as only being sent when the user changes the color
- gtk_color_chooser_set_rgba(b->cc, &rgba);
-}
-
-void uiColorButtonOnChanged(uiColorButton *b, void (*f)(uiColorButton *, void *), void *data)
-{
- b->onChanged = f;
- b->onChangedData = data;
-}
-
-uiColorButton *uiNewColorButton(void)
-{
- uiColorButton *b;
- GdkRGBA black;
-
- uiUnixNewControl(uiColorButton, b);
-
- // I'm not sure what the initial color is; set up a real one
- black.red = 0.0;
- black.green = 0.0;
- black.blue = 0.0;
- black.alpha = 1.0;
- b->widget = gtk_color_button_new_with_rgba(&black);
- b->button = GTK_BUTTON(b->widget);
- b->cb = GTK_COLOR_BUTTON(b->widget);
- b->cc = GTK_COLOR_CHOOSER(b->widget);
-
- gtk_color_chooser_set_use_alpha(b->cc, TRUE);
-
- g_signal_connect(b->widget, "color-set", G_CALLBACK(onColorSet), b);
- uiColorButtonOnChanged(b, defaultOnChanged, NULL);
-
- return b;
-}
diff --git a/src/libui_sdl/libui/unix/combobox.c b/src/libui_sdl/libui/unix/combobox.c
deleted file mode 100644
index 6fed804..0000000
--- a/src/libui_sdl/libui/unix/combobox.c
+++ /dev/null
@@ -1,66 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiCombobox {
- uiUnixControl c;
- GtkWidget *widget;
- GtkComboBox *combobox;
- GtkComboBoxText *comboboxText;
- void (*onSelected)(uiCombobox *, void *);
- void *onSelectedData;
- gulong onSelectedSignal;
-};
-
-uiUnixControlAllDefaults(uiCombobox)
-
-static void onChanged(GtkComboBox *cbox, gpointer data)
-{
- uiCombobox *c = uiCombobox(data);
-
- (*(c->onSelected))(c, c->onSelectedData);
-}
-
-static void defaultOnSelected(uiCombobox *c, void *data)
-{
- // do nothing
-}
-
-void uiComboboxAppend(uiCombobox *c, const char *text)
-{
- gtk_combo_box_text_append(c->comboboxText, NULL, text);
-}
-
-int uiComboboxSelected(uiCombobox *c)
-{
- return gtk_combo_box_get_active(c->combobox);
-}
-
-void uiComboboxSetSelected(uiCombobox *c, int n)
-{
- // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
- g_signal_handler_block(c->combobox, c->onSelectedSignal);
- gtk_combo_box_set_active(c->combobox, n);
- g_signal_handler_unblock(c->combobox, c->onSelectedSignal);
-}
-
-void uiComboboxOnSelected(uiCombobox *c, void (*f)(uiCombobox *c, void *data), void *data)
-{
- c->onSelected = f;
- c->onSelectedData = data;
-}
-
-uiCombobox *uiNewCombobox(void)
-{
- uiCombobox *c;
-
- uiUnixNewControl(uiCombobox, c);
-
- c->widget = gtk_combo_box_text_new();
- c->combobox = GTK_COMBO_BOX(c->widget);
- c->comboboxText = GTK_COMBO_BOX_TEXT(c->widget);
-
- c->onSelectedSignal = g_signal_connect(c->widget, "changed", G_CALLBACK(onChanged), c);
- uiComboboxOnSelected(c, defaultOnSelected, NULL);
-
- return c;
-}
diff --git a/src/libui_sdl/libui/unix/control.c b/src/libui_sdl/libui/unix/control.c
deleted file mode 100644
index f6fdcea..0000000
--- a/src/libui_sdl/libui/unix/control.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// 16 august 2015
-#include "uipriv_unix.h"
-
-void uiUnixControlSetContainer(uiUnixControl *c, GtkContainer *container, gboolean remove)
-{
- (*(c->SetContainer))(c, container, remove);
-}
-
-#define uiUnixControlSignature 0x556E6978
-
-uiUnixControl *uiUnixAllocControl(size_t n, uint32_t typesig, const char *typenamestr)
-{
- return uiUnixControl(uiAllocControl(n, uiUnixControlSignature, typesig, typenamestr));
-}
diff --git a/src/libui_sdl/libui/unix/datetimepicker.c b/src/libui_sdl/libui/unix/datetimepicker.c
deleted file mode 100644
index 19689a2..0000000
--- a/src/libui_sdl/libui/unix/datetimepicker.c
+++ /dev/null
@@ -1,599 +0,0 @@
-// 4 september 2015
-#include "uipriv_unix.h"
-
-// LONGTERM imitate gnome-calendar's day/month/year entries above the calendar
-// LONGTERM allow entering a 24-hour hour in the hour spinbutton and adjust accordingly
-
-#define dateTimePickerWidgetType (dateTimePickerWidget_get_type())
-#define dateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), dateTimePickerWidgetType, dateTimePickerWidget))
-#define isDateTimePickerWidget(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), dateTimePickerWidgetType))
-#define dateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_CAST((class), dateTimePickerWidgetType, dateTimePickerWidgetClass))
-#define isDateTimePickerWidgetClass(class) (G_TYPE_CHECK_CLASS_TYPE((class), dateTimePickerWidget))
-#define getDateTimePickerWidgetClass(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), dateTimePickerWidgetType, dateTimePickerWidgetClass))
-
-typedef struct dateTimePickerWidget dateTimePickerWidget;
-typedef struct dateTimePickerWidgetClass dateTimePickerWidgetClass;
-
-struct dateTimePickerWidget {
- GtkToggleButton parent_instance;
-
- gulong toggledSignal;
-
- gboolean hasTime;
- gboolean hasDate;
-
- GtkWidget *window;
- GtkWidget *box;
- GtkWidget *calendar;
- GtkWidget *timebox;
- GtkWidget *hours;
- GtkWidget *minutes;
- GtkWidget *seconds;
- GtkWidget *ampm;
-
- gulong hoursBlock;
- gulong minutesBlock;
- gulong secondsBlock;
- gulong ampmBlock;
-
- GdkDevice *keyboard;
- GdkDevice *mouse;
-};
-
-struct dateTimePickerWidgetClass {
- GtkToggleButtonClass parent_class;
-};
-
-G_DEFINE_TYPE(dateTimePickerWidget, dateTimePickerWidget, GTK_TYPE_TOGGLE_BUTTON)
-
-static int realSpinValue(GtkSpinButton *spinButton)
-{
- GtkAdjustment *adj;
-
- adj = gtk_spin_button_get_adjustment(spinButton);
- return (int) gtk_adjustment_get_value(adj);
-}
-
-static void setRealSpinValue(GtkSpinButton *spinButton, int value, gulong block)
-{
- GtkAdjustment *adj;
-
- g_signal_handler_block(spinButton, block);
- adj = gtk_spin_button_get_adjustment(spinButton);
- gtk_adjustment_set_value(adj, value);
- g_signal_handler_unblock(spinButton, block);
-}
-
-static GDateTime *selected(dateTimePickerWidget *d)
-{
- // choose a day for which all times are likely to be valid for the default date in case we're only dealing with time
- guint year = 1970, month = 1, day = 1;
- guint hour = 0, minute = 0, second = 0;
-
- if (d->hasDate) {
- gtk_calendar_get_date(GTK_CALENDAR(d->calendar), &year, &month, &day);
- month++; // GtkCalendar/GDateTime differences
- }
- if (d->hasTime) {
- hour = realSpinValue(GTK_SPIN_BUTTON(d->hours));
- if (realSpinValue(GTK_SPIN_BUTTON(d->ampm)) != 0)
- hour += 12;
- minute = realSpinValue(GTK_SPIN_BUTTON(d->minutes));
- second = realSpinValue(GTK_SPIN_BUTTON(d->seconds));
- }
- return g_date_time_new_local(year, month, day, hour, minute, second);
-}
-
-static void setLabel(dateTimePickerWidget *d)
-{
- GDateTime *dt;
- char *fmt;
- char *msg;
- gboolean free;
-
- dt = selected(d);
- free = FALSE;
- if (d->hasDate && d->hasTime) {
- // don't use D_T_FMT; that's too verbose
- fmt = g_strdup_printf("%s %s", nl_langinfo(D_FMT), nl_langinfo(T_FMT));
- free = TRUE;
- } else if (d->hasDate)
- fmt = nl_langinfo(D_FMT);
- else
- fmt = nl_langinfo(T_FMT);
- msg = g_date_time_format(dt, fmt);
- gtk_button_set_label(GTK_BUTTON(d), msg);
- g_free(msg);
- if (free)
- g_free(fmt);
- g_date_time_unref(dt);
-}
-
-static void dateTimeChanged(dateTimePickerWidget *d)
-{
- setLabel(d);
- // TODO fire event here
-}
-
-// we don't want ::toggled to be sent again
-static void setActive(dateTimePickerWidget *d, gboolean active)
-{
- g_signal_handler_block(d, d->toggledSignal);
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(d), active);
- g_signal_handler_unblock(d, d->toggledSignal);
-}
-
-// like startGrab() below, a lot of this is in the order that GtkComboBox does it
-static void endGrab(dateTimePickerWidget *d)
-{
- if (d->keyboard != NULL)
- gdk_device_ungrab(d->keyboard, GDK_CURRENT_TIME);
- gdk_device_ungrab(d->mouse, GDK_CURRENT_TIME);
- gtk_device_grab_remove(d->window, d->mouse);
- d->keyboard = NULL;
- d->mouse = NULL;
-}
-
-static void hidePopup(dateTimePickerWidget *d)
-{
- endGrab(d);
- gtk_widget_hide(d->window);
- setActive(d, FALSE);
-}
-
-// this consolidates a good chunk of what GtkComboBox does
-static gboolean startGrab(dateTimePickerWidget *d)
-{
- GdkDevice *dev;
- guint32 time;
- GdkWindow *window;
- GdkDevice *keyboard, *mouse;
-
- dev = gtk_get_current_event_device();
- if (dev == NULL) {
- // this is what GtkComboBox does
- // since no device was set, just use the first available "master device"
- GdkDisplay *disp;
- GdkDeviceManager *dm;
- GList *list;
-
- disp = gtk_widget_get_display(GTK_WIDGET(d));
- dm = gdk_display_get_device_manager(disp);
- list = gdk_device_manager_list_devices(dm, GDK_DEVICE_TYPE_MASTER);
- dev = (GdkDevice *) (list->data);
- g_list_free(list);
- }
-
- time = gtk_get_current_event_time();
- keyboard = dev;
- mouse = gdk_device_get_associated_device(dev);
- if (gdk_device_get_source(dev) != GDK_SOURCE_KEYBOARD) {
- dev = mouse;
- mouse = keyboard;
- keyboard = dev;
- }
-
- window = gtk_widget_get_window(d->window);
- if (keyboard != NULL)
- if (gdk_device_grab(keyboard, window,
- GDK_OWNERSHIP_WINDOW, TRUE,
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK,
- NULL, time) != GDK_GRAB_SUCCESS)
- return FALSE;
- if (mouse != NULL)
- if (gdk_device_grab(mouse, window,
- GDK_OWNERSHIP_WINDOW, TRUE,
- GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK,
- NULL, time) != GDK_GRAB_SUCCESS) {
- if (keyboard != NULL)
- gdk_device_ungrab(keyboard, time);
- return FALSE;
- }
-
- gtk_device_grab_add(d->window, mouse, TRUE);
- d->keyboard = keyboard;
- d->mouse = mouse;
- return TRUE;
-}
-
-// based on gtk_combo_box_list_position() in the GTK+ source code
-static void allocationToScreen(dateTimePickerWidget *d, gint *x, gint *y)
-{
- GdkWindow *window;
- GtkAllocation a;
- GtkRequisition aWin;
- GdkScreen *screen;
- GdkRectangle workarea;
- int otherY;
-
- gtk_widget_get_allocation(GTK_WIDGET(d), &a);
- gtk_widget_get_preferred_size(d->window, &aWin, NULL);
- *x = 0;
- *y = 0;
- if (!gtk_widget_get_has_window(GTK_WIDGET(d))) {
- *x = a.x;
- *y = a.y;
- }
- window = gtk_widget_get_window(GTK_WIDGET(d));
- gdk_window_get_root_coords(window, *x, *y, x, y);
- if (gtk_widget_get_direction(GTK_WIDGET(d)) == GTK_TEXT_DIR_RTL)
- *x += a.width - aWin.width;
-
- // now adjust to prevent the box from going offscreen
- screen = gtk_widget_get_screen(GTK_WIDGET(d));
- gdk_screen_get_monitor_workarea(screen,
- gdk_screen_get_monitor_at_window(screen, window),
- &workarea);
- if (*x < workarea.x) // too far to the left?
- *x = workarea.x;
- else if (*x + aWin.width > (workarea.x + workarea.width)) // too far to the right?
- *x = (workarea.x + workarea.width) - aWin.width;
- // this isn't the same algorithm used by GtkComboBox
- // first, get our two choices; *y for down and otherY for up
- otherY = *y - aWin.height;
- *y += a.height;
- // and use otherY if we're too low
- if (*y + aWin.height >= workarea.y + workarea.height)
- *y = otherY;
-}
-
-static void showPopup(dateTimePickerWidget *d)
-{
- GtkWidget *toplevel;
- gint x, y;
-
- // GtkComboBox does it
- toplevel = gtk_widget_get_toplevel(GTK_WIDGET(d));
- if (GTK_IS_WINDOW(toplevel))
- gtk_window_group_add_window(gtk_window_get_group(GTK_WINDOW(toplevel)), GTK_WINDOW(d->window));
-
- allocationToScreen(d, &x, &y);
- gtk_window_move(GTK_WINDOW(d->window), x, y);
-
- gtk_widget_show(d->window);
- setActive(d, TRUE);
-
- if (!startGrab(d))
- hidePopup(d);
-}
-
-static void onToggled(GtkToggleButton *b, gpointer data)
-{
- dateTimePickerWidget *d = dateTimePickerWidget(b);
-
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(d)))
- showPopup(d);
- else
- hidePopup(d);
-}
-
-static gboolean grabBroken(GtkWidget *w, GdkEventGrabBroken *e, gpointer data)
-{
- dateTimePickerWidget *d = dateTimePickerWidget(data);
-
- hidePopup(d);
- return TRUE; // this is what GtkComboBox does
-}
-
-static gboolean buttonReleased(GtkWidget *w, GdkEventButton *e, gpointer data)
-{
- dateTimePickerWidget *d = dateTimePickerWidget(data);
- int winx, winy;
- GtkAllocation wina;
- gboolean in;
-
- gtk_widget_get_allocation(d->window, &wina);
- winx = 0;
- winy = 0;
- if (!gtk_widget_get_has_window(d->window)) {
- winx = wina.x;
- winy = wina.y;
- }
- gdk_window_get_root_coords(gtk_widget_get_window(d->window), winx, winy, &winx, &winy);
- in = TRUE;
- if (e->x_root < winx)
- in = FALSE;
- if (e->x_root >= (winx + wina.width))
- in = FALSE;
- if (e->y_root < winy)
- in = FALSE;
- if (e->y_root >= (winy + wina.height))
- in = FALSE;
- if (!in)
- hidePopup(d);
- return TRUE; // this is what GtkComboBox does
-}
-
-static gint hoursSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data)
-{
- double *out = (double *) ptr;
- const gchar *text;
- int value;
-
- text = gtk_entry_get_text(GTK_ENTRY(sb));
- value = (int) g_strtod(text, NULL);
- if (value < 0 || value > 12)
- return GTK_INPUT_ERROR;
- if (value == 12) // 12 to the user is 0 internally
- value = 0;
- *out = (double) value;
- return TRUE;
-}
-
-static gboolean hoursSpinboxOutput(GtkSpinButton *sb, gpointer data)
-{
- gchar *text;
- int value;
-
- value = realSpinValue(sb);
- if (value == 0) // 0 internally is 12 to the user
- value = 12;
- text = g_strdup_printf("%d", value);
- gtk_entry_set_text(GTK_ENTRY(sb), text);
- g_free(text);
- return TRUE;
-}
-
-static gboolean zeroPadSpinbox(GtkSpinButton *sb, gpointer data)
-{
- gchar *text;
- int value;
-
- value = realSpinValue(sb);
- text = g_strdup_printf("%02d", value);
- gtk_entry_set_text(GTK_ENTRY(sb), text);
- g_free(text);
- return TRUE;
-}
-
-// this is really hacky but we can't use GtkCombobox here :(
-static gint ampmSpinboxInput(GtkSpinButton *sb, gpointer ptr, gpointer data)
-{
- double *out = (double *) ptr;
- const gchar *text;
- char firstAM, firstPM;
-
- text = gtk_entry_get_text(GTK_ENTRY(sb));
- // LONGTERM don't use ASCII here for case insensitivity
- firstAM = g_ascii_tolower(nl_langinfo(AM_STR)[0]);
- firstPM = g_ascii_tolower(nl_langinfo(PM_STR)[0]);
- for (; *text != '\0'; text++)
- if (g_ascii_tolower(*text) == firstAM) {
- *out = 0;
- return TRUE;
- } else if (g_ascii_tolower(*text) == firstPM) {
- *out = 1;
- return TRUE;
- }
- return GTK_INPUT_ERROR;
-}
-
-static gboolean ampmSpinboxOutput(GtkSpinButton *sb, gpointer data)
-{
- int value;
-
- value = gtk_spin_button_get_value_as_int(sb);
- if (value == 0)
- gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(AM_STR));
- else
- gtk_entry_set_text(GTK_ENTRY(sb), nl_langinfo(PM_STR));
- return TRUE;
-}
-
-static void spinboxChanged(GtkSpinButton *sb, gpointer data)
-{
- dateTimePickerWidget *d = dateTimePickerWidget(data);
-
- dateTimeChanged(d);
-}
-
-static GtkWidget *newSpinbox(dateTimePickerWidget *d, int min, int max, gint (*input)(GtkSpinButton *, gpointer, gpointer), gboolean (*output)(GtkSpinButton *, gpointer), gulong *block)
-{
- GtkWidget *sb;
-
- sb = gtk_spin_button_new_with_range(min, max, 1);
- gtk_spin_button_set_digits(GTK_SPIN_BUTTON(sb), 0);
- gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(sb), TRUE);
- gtk_orientable_set_orientation(GTK_ORIENTABLE(sb), GTK_ORIENTATION_VERTICAL);
- *block = g_signal_connect(sb, "value-changed", G_CALLBACK(spinboxChanged), d);
- if (input != NULL)
- g_signal_connect(sb, "input", G_CALLBACK(input), NULL);
- if (output != NULL)
- g_signal_connect(sb, "output", G_CALLBACK(output), NULL);
- return sb;
-}
-
-static void dateChanged(GtkCalendar *c, gpointer data)
-{
- dateTimePickerWidget *d = dateTimePickerWidget(data);
-
- dateTimeChanged(d);
-}
-
-static void setDateOnly(dateTimePickerWidget *d)
-{
- d->hasTime = FALSE;
- gtk_container_remove(GTK_CONTAINER(d->box), d->timebox);
-}
-
-static void setTimeOnly(dateTimePickerWidget *d)
-{
- d->hasDate = FALSE;
- gtk_container_remove(GTK_CONTAINER(d->box), d->calendar);
-}
-
-static void dateTimePickerWidget_init(dateTimePickerWidget *d)
-{
- GDateTime *dt;
- gint year, month, day;
- gint hour;
- gulong calendarBlock;
-
- d->window = gtk_window_new(GTK_WINDOW_POPUP);
- gtk_window_set_resizable(GTK_WINDOW(d->window), FALSE);
- gtk_window_set_attached_to(GTK_WINDOW(d->window), GTK_WIDGET(d));
- gtk_window_set_decorated(GTK_WINDOW(d->window), FALSE);
- gtk_window_set_deletable(GTK_WINDOW(d->window), FALSE);
- gtk_window_set_type_hint(GTK_WINDOW(d->window), GDK_WINDOW_TYPE_HINT_COMBO);
- gtk_window_set_skip_taskbar_hint(GTK_WINDOW(d->window), TRUE);
- gtk_window_set_skip_pager_hint(GTK_WINDOW(d->window), TRUE);
- gtk_window_set_has_resize_grip(GTK_WINDOW(d->window), FALSE);
- gtk_container_set_border_width(GTK_CONTAINER(d->window), 12);
- // and make it stand out a bit
- gtk_style_context_add_class(gtk_widget_get_style_context(d->window), "frame");
-
- d->box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
- gtk_container_add(GTK_CONTAINER(d->window), d->box);
-
- d->calendar = gtk_calendar_new();
- calendarBlock = g_signal_connect(d->calendar, "day-selected", G_CALLBACK(dateChanged), d);
- gtk_container_add(GTK_CONTAINER(d->box), d->calendar);
-
- d->timebox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6);
- gtk_widget_set_valign(d->timebox, GTK_ALIGN_CENTER);
- gtk_container_add(GTK_CONTAINER(d->box), d->timebox);
-
- d->hours = newSpinbox(d, 0, 11, hoursSpinboxInput, hoursSpinboxOutput, &(d->hoursBlock));
- gtk_container_add(GTK_CONTAINER(d->timebox), d->hours);
-
- gtk_container_add(GTK_CONTAINER(d->timebox),
- gtk_label_new(":"));
-
- d->minutes = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->minutesBlock));
- gtk_container_add(GTK_CONTAINER(d->timebox), d->minutes);
-
- gtk_container_add(GTK_CONTAINER(d->timebox),
- gtk_label_new(":"));
-
- d->seconds = newSpinbox(d, 0, 59, NULL, zeroPadSpinbox, &(d->secondsBlock));
- gtk_container_add(GTK_CONTAINER(d->timebox), d->seconds);
-
- // LONGTERM this should be the case, but that interferes with grabs
- // switch to it when we can drop GTK+ 3.10 and use popovers
-#if 0
- d->ampm = gtk_combo_box_text_new();
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "AM");
- gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(d->ampm), NULL, "PM");
-#endif
- d->ampm = newSpinbox(d, 0, 1, ampmSpinboxInput, ampmSpinboxOutput, &(d->ampmBlock));
- gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(d->ampm), FALSE);
- gtk_widget_set_valign(d->ampm, GTK_ALIGN_CENTER);
- gtk_container_add(GTK_CONTAINER(d->timebox), d->ampm);
-
- gtk_widget_show_all(d->box);
-
- g_signal_connect(d->window, "grab-broken-event", G_CALLBACK(grabBroken), d);
- g_signal_connect(d->window, "button-release-event", G_CALLBACK(buttonReleased), d);
-
- d->toggledSignal = g_signal_connect(d, "toggled", G_CALLBACK(onToggled), NULL);
- d->keyboard = NULL;
- d->mouse = NULL;
-
- d->hasTime = TRUE;
- d->hasDate = TRUE;
-
- // set the current date/time
- // notice how we block signals from firing
- dt = g_date_time_new_now_local();
- g_date_time_get_ymd(dt, &year, &month, &day);
- month--; // GDateTime/GtkCalendar differences
- g_signal_handler_block(d->calendar, calendarBlock);
- gtk_calendar_select_month(GTK_CALENDAR(d->calendar), month, year);
- gtk_calendar_select_day(GTK_CALENDAR(d->calendar), day);
- g_signal_handler_unblock(d->calendar, calendarBlock);
- hour = g_date_time_get_hour(dt);
- if (hour >= 12) {
- hour -= 12;
- setRealSpinValue(GTK_SPIN_BUTTON(d->ampm), 1, d->ampmBlock);
- }
- setRealSpinValue(GTK_SPIN_BUTTON(d->hours), hour, d->hoursBlock);
- setRealSpinValue(GTK_SPIN_BUTTON(d->minutes), g_date_time_get_minute(dt), d->minutesBlock);
- setRealSpinValue(GTK_SPIN_BUTTON(d->seconds), g_date_time_get_seconds(dt), d->secondsBlock);
- g_date_time_unref(dt);
-}
-
-static void dateTimePickerWidget_dispose(GObject *obj)
-{
- dateTimePickerWidget *d = dateTimePickerWidget(obj);
-
- if (d->window != NULL) {
- gtk_widget_destroy(d->window);
- d->window = NULL;
- }
- G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->dispose(obj);
-}
-
-static void dateTimePickerWidget_finalize(GObject *obj)
-{
- G_OBJECT_CLASS(dateTimePickerWidget_parent_class)->finalize(obj);
-}
-
-static void dateTimePickerWidget_class_init(dateTimePickerWidgetClass *class)
-{
- G_OBJECT_CLASS(class)->dispose = dateTimePickerWidget_dispose;
- G_OBJECT_CLASS(class)->finalize = dateTimePickerWidget_finalize;
-}
-
-static GtkWidget *newDTP(void)
-{
- GtkWidget *w;
-
- w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL));
- setLabel(dateTimePickerWidget(w));
- return w;
-}
-
-static GtkWidget *newDP(void)
-{
- GtkWidget *w;
-
- w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL));
- setDateOnly(dateTimePickerWidget(w));
- setLabel(dateTimePickerWidget(w));
- return w;
-}
-
-static GtkWidget *newTP(void)
-{
- GtkWidget *w;
-
- w = GTK_WIDGET(g_object_new(dateTimePickerWidgetType, "label", "", NULL));
- setTimeOnly(dateTimePickerWidget(w));
- setLabel(dateTimePickerWidget(w));
- return w;
-}
-
-struct uiDateTimePicker {
- uiUnixControl c;
- GtkWidget *widget;
- dateTimePickerWidget *d;
-};
-
-uiUnixControlAllDefaults(uiDateTimePicker)
-
-uiDateTimePicker *finishNewDateTimePicker(GtkWidget *(*fn)(void))
-{
- uiDateTimePicker *d;
-
- uiUnixNewControl(uiDateTimePicker, d);
-
- d->widget = (*fn)();
- d->d = dateTimePickerWidget(d->widget);
-
- return d;
-}
-
-uiDateTimePicker *uiNewDateTimePicker(void)
-{
- return finishNewDateTimePicker(newDTP);
-}
-
-uiDateTimePicker *uiNewDatePicker(void)
-{
- return finishNewDateTimePicker(newDP);
-}
-
-uiDateTimePicker *uiNewTimePicker(void)
-{
- return finishNewDateTimePicker(newTP);
-}
diff --git a/src/libui_sdl/libui/unix/debug.c b/src/libui_sdl/libui/unix/debug.c
deleted file mode 100644
index c948db6..0000000
--- a/src/libui_sdl/libui/unix/debug.c
+++ /dev/null
@@ -1,14 +0,0 @@
-// 13 may 2016
-#include "uipriv_unix.h"
-
-// LONGTERM don't halt on release builds
-
-void realbug(const char *file, const char *line, const char *func, const char *prefix, const char *format, va_list ap)
-{
- char *a, *b;
-
- a = g_strdup_printf("[libui] %s:%s:%s() %s", file, line, func, prefix);
- b = g_strdup_vprintf(format, ap);
- g_critical("%s%s", a, b);
- G_BREAKPOINT();
-}
diff --git a/src/libui_sdl/libui/unix/draw.c b/src/libui_sdl/libui/unix/draw.c
deleted file mode 100644
index 5befcd3..0000000
--- a/src/libui_sdl/libui/unix/draw.c
+++ /dev/null
@@ -1,214 +0,0 @@
-// 6 september 2015
-#include "uipriv_unix.h"
-#include "draw.h"
-
-uiDrawContext *newContext(cairo_t *cr)
-{
- uiDrawContext *c;
-
- c = uiNew(uiDrawContext);
- c->cr = cr;
- return c;
-}
-
-void freeContext(uiDrawContext *c)
-{
- uiFree(c);
-}
-
-static cairo_pattern_t *mkbrush(uiDrawBrush *b)
-{
- cairo_pattern_t *pat;
- size_t i;
-
- switch (b->Type) {
- case uiDrawBrushTypeSolid:
- pat = cairo_pattern_create_rgba(b->R, b->G, b->B, b->A);
- break;
- case uiDrawBrushTypeLinearGradient:
- pat = cairo_pattern_create_linear(b->X0, b->Y0, b->X1, b->Y1);
- break;
- case uiDrawBrushTypeRadialGradient:
- // make the start circle radius 0 to make it a point
- pat = cairo_pattern_create_radial(
- b->X0, b->Y0, 0,
- b->X1, b->Y1, b->OuterRadius);
- break;
-// case uiDrawBrushTypeImage:
- }
- if (cairo_pattern_status(pat) != CAIRO_STATUS_SUCCESS)
- implbug("error creating pattern in mkbrush(): %s",
- cairo_status_to_string(cairo_pattern_status(pat)));
- switch (b->Type) {
- case uiDrawBrushTypeLinearGradient:
- case uiDrawBrushTypeRadialGradient:
- for (i = 0; i < b->NumStops; i++)
- cairo_pattern_add_color_stop_rgba(pat,
- b->Stops[i].Pos,
- b->Stops[i].R,
- b->Stops[i].G,
- b->Stops[i].B,
- b->Stops[i].A);
- }
- return pat;
-}
-
-void uiDrawStroke(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b, uiDrawStrokeParams *p)
-{
- cairo_pattern_t *pat;
-
- runPath(path, c->cr);
- pat = mkbrush(b);
- cairo_set_source(c->cr, pat);
- switch (p->Cap) {
- case uiDrawLineCapFlat:
- cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_BUTT);
- break;
- case uiDrawLineCapRound:
- cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_ROUND);
- break;
- case uiDrawLineCapSquare:
- cairo_set_line_cap(c->cr, CAIRO_LINE_CAP_SQUARE);
- break;
- }
- switch (p->Join) {
- case uiDrawLineJoinMiter:
- cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_MITER);
- cairo_set_miter_limit(c->cr, p->MiterLimit);
- break;
- case uiDrawLineJoinRound:
- cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_ROUND);
- break;
- case uiDrawLineJoinBevel:
- cairo_set_line_join(c->cr, CAIRO_LINE_JOIN_BEVEL);
- break;
- }
- cairo_set_line_width(c->cr, p->Thickness);
- cairo_set_dash(c->cr, p->Dashes, p->NumDashes, p->DashPhase);
- cairo_stroke(c->cr);
- cairo_pattern_destroy(pat);
-}
-
-void uiDrawFill(uiDrawContext *c, uiDrawPath *path, uiDrawBrush *b)
-{
- cairo_pattern_t *pat;
-
- runPath(path, c->cr);
- pat = mkbrush(b);
- cairo_set_source(c->cr, pat);
- switch (pathFillMode(path)) {
- case uiDrawFillModeWinding:
- cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_WINDING);
- break;
- case uiDrawFillModeAlternate:
- cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_EVEN_ODD);
- break;
- }
- cairo_fill(c->cr);
- cairo_pattern_destroy(pat);
-}
-
-void uiDrawTransform(uiDrawContext *c, uiDrawMatrix *m)
-{
- cairo_matrix_t cm;
-
- m2c(m, &cm);
- cairo_transform(c->cr, &cm);
-}
-
-void uiDrawClip(uiDrawContext *c, uiDrawPath *path)
-{
- runPath(path, c->cr);
- switch (pathFillMode(path)) {
- case uiDrawFillModeWinding:
- cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_WINDING);
- break;
- case uiDrawFillModeAlternate:
- cairo_set_fill_rule(c->cr, CAIRO_FILL_RULE_EVEN_ODD);
- break;
- }
- cairo_clip(c->cr);
-}
-
-void uiDrawSave(uiDrawContext *c)
-{
- cairo_save(c->cr);
-}
-
-void uiDrawRestore(uiDrawContext *c)
-{
- cairo_restore(c->cr);
-}
-
-
-// bitmap API
-
-uiDrawBitmap* uiDrawNewBitmap(uiDrawContext* c, int width, int height, int alpha)
-{
- uiDrawBitmap* bmp;
-
- bmp = uiNew(uiDrawBitmap);
-
- bmp->bmp = cairo_image_surface_create(alpha ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24, width, height);
- if (cairo_surface_status(bmp->bmp) != CAIRO_STATUS_SUCCESS)
- implbug("error creating bitmap: %s",
- cairo_status_to_string(cairo_surface_status(bmp->bmp)));
-
- bmp->Width = width;
- bmp->Height = height;
- bmp->Stride = cairo_image_surface_get_stride(bmp->bmp);
-
- return bmp;
-}
-
-void uiDrawBitmapUpdate(uiDrawBitmap* bmp, const void* data)
-{
- const unsigned char* src = data;
- unsigned char* dst = cairo_image_surface_get_data(bmp->bmp);
-
- if (bmp->Stride == bmp->Width*4)
- {
- // stride 'good', can just directly copy all the shit
- memcpy(dst, src, bmp->Stride*bmp->Height);
- }
- else
- {
- int y;
- for (y = 0; y < bmp->Height; y++)
- {
- memcpy(dst, src, bmp->Width*4);
- src += bmp->Width*4;
- dst += bmp->Stride;
- }
- }
-
- cairo_surface_mark_dirty(bmp->bmp);
-}
-
-void uiDrawBitmapDraw(uiDrawContext* c, uiDrawBitmap* bmp, uiRect* srcrect, uiRect* dstrect, int filter)
-{
- cairo_save(c->cr);
- cairo_rectangle(c->cr, dstrect->X, dstrect->Y, dstrect->Width, dstrect->Height);
-
- cairo_translate(c->cr, dstrect->X, dstrect->Y);
- if ((dstrect->Width != srcrect->Width) || (dstrect->Height != srcrect->Height))
- {
- // scale shit if needed
- double sx = dstrect->Width / (double)srcrect->Width;
- double sy = dstrect->Height / (double)srcrect->Height;
- cairo_scale(c->cr, sx, sy);
- }
-
- cairo_set_source_surface(c->cr, bmp->bmp, -srcrect->X, -srcrect->Y);
- cairo_pattern_set_filter(cairo_get_source(c->cr), filter ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_NEAREST);
- cairo_clip(c->cr);
- cairo_paint(c->cr);
-
- cairo_restore(c->cr);
-}
-
-void uiDrawFreeBitmap(uiDrawBitmap* bmp)
-{
- cairo_surface_destroy(bmp->bmp);
- uiFree(bmp);
-}
diff --git a/src/libui_sdl/libui/unix/draw.h b/src/libui_sdl/libui/unix/draw.h
deleted file mode 100644
index 869acd1..0000000
--- a/src/libui_sdl/libui/unix/draw.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// 5 may 2016
-
-// draw.c
-struct uiDrawContext {
- cairo_t *cr;
-};
-
-struct uiDrawBitmap {
- int Width;
- int Height;
- int Stride;
-
- cairo_surface_t* bmp;
-};
-
-// drawpath.c
-extern void runPath(uiDrawPath *p, cairo_t *cr);
-extern uiDrawFillMode pathFillMode(uiDrawPath *path);
-
-// drawmatrix.c
-extern void m2c(uiDrawMatrix *m, cairo_matrix_t *c);
diff --git a/src/libui_sdl/libui/unix/drawmatrix.c b/src/libui_sdl/libui/unix/drawmatrix.c
deleted file mode 100644
index f12b303..0000000
--- a/src/libui_sdl/libui/unix/drawmatrix.c
+++ /dev/null
@@ -1,115 +0,0 @@
-// 6 september 2015
-#include "uipriv_unix.h"
-#include "draw.h"
-
-void m2c(uiDrawMatrix *m, cairo_matrix_t *c)
-{
- c->xx = m->M11;
- c->yx = m->M12;
- c->xy = m->M21;
- c->yy = m->M22;
- c->x0 = m->M31;
- c->y0 = m->M32;
-}
-
-static void c2m(cairo_matrix_t *c, uiDrawMatrix *m)
-{
- m->M11 = c->xx;
- m->M12 = c->yx;
- m->M21 = c->xy;
- m->M22 = c->yy;
- m->M31 = c->x0;
- m->M32 = c->y0;
-}
-
-void uiDrawMatrixTranslate(uiDrawMatrix *m, double x, double y)
-{
- cairo_matrix_t c;
- cairo_matrix_t tmp;
-
- m2c(m, &c);
- cairo_matrix_init_translate(&tmp, x, y);
- cairo_matrix_multiply(&c, &c, &tmp);
- c2m(&c, m);
-}
-
-void uiDrawMatrixScale(uiDrawMatrix *m, double xCenter, double yCenter, double x, double y)
-{
- cairo_matrix_t c;
- cairo_matrix_t tmp;
- double xt, yt;
-
- m2c(m, &c);
- xt = x;
- yt = y;
- scaleCenter(xCenter, yCenter, &xt, &yt);
- cairo_matrix_init_translate(&tmp, xt, yt);
- cairo_matrix_scale(&tmp, x, y);
- cairo_matrix_translate(&tmp, -xt, -yt);
- cairo_matrix_multiply(&c, &c, &tmp);
- c2m(&c, m);
-}
-
-void uiDrawMatrixRotate(uiDrawMatrix *m, double x, double y, double amount)
-{
- cairo_matrix_t c;
- cairo_matrix_t tmp;
-
- m2c(m, &c);
- cairo_matrix_init_translate(&tmp, x, y);
- cairo_matrix_rotate(&tmp, amount);
- cairo_matrix_translate(&tmp, -x, -y);
- cairo_matrix_multiply(&c, &c, &tmp);
- c2m(&c, m);
-}
-
-void uiDrawMatrixSkew(uiDrawMatrix *m, double x, double y, double xamount, double yamount)
-{
- fallbackSkew(m, x, y, xamount, yamount);
-}
-
-void uiDrawMatrixMultiply(uiDrawMatrix *dest, uiDrawMatrix *src)
-{
- cairo_matrix_t c;
- cairo_matrix_t d;
-
- m2c(dest, &c);
- m2c(src, &d);
- cairo_matrix_multiply(&c, &c, &d);
- c2m(&c, dest);
-}
-
-int uiDrawMatrixInvertible(uiDrawMatrix *m)
-{
- cairo_matrix_t c;
-
- m2c(m, &c);
- return cairo_matrix_invert(&c) == CAIRO_STATUS_SUCCESS;
-}
-
-int uiDrawMatrixInvert(uiDrawMatrix *m)
-{
- cairo_matrix_t c;
-
- m2c(m, &c);
- if (cairo_matrix_invert(&c) != CAIRO_STATUS_SUCCESS)
- return 0;
- c2m(&c, m);
- return 1;
-}
-
-void uiDrawMatrixTransformPoint(uiDrawMatrix *m, double *x, double *y)
-{
- cairo_matrix_t c;
-
- m2c(m, &c);
- cairo_matrix_transform_point(&c, x, y);
-}
-
-void uiDrawMatrixTransformSize(uiDrawMatrix *m, double *x, double *y)
-{
- cairo_matrix_t c;
-
- m2c(m, &c);
- cairo_matrix_transform_distance(&c, x, y);
-}
diff --git a/src/libui_sdl/libui/unix/drawpath.c b/src/libui_sdl/libui/unix/drawpath.c
deleted file mode 100644
index a0165fb..0000000
--- a/src/libui_sdl/libui/unix/drawpath.c
+++ /dev/null
@@ -1,199 +0,0 @@
-// 6 september 2015
-#include "uipriv_unix.h"
-#include "draw.h"
-
-struct uiDrawPath {
- GArray *pieces;
- uiDrawFillMode fillMode;
- gboolean ended;
-};
-
-struct piece {
- int type;
- double d[8];
- int b;
-};
-
-enum {
- newFigure,
- newFigureArc,
- lineTo,
- arcTo,
- bezierTo,
- closeFigure,
- addRect,
-};
-
-uiDrawPath *uiDrawNewPath(uiDrawFillMode mode)
-{
- uiDrawPath *p;
-
- p = uiNew(uiDrawPath);
- p->pieces = g_array_new(FALSE, TRUE, sizeof (struct piece));
- p->fillMode = mode;
- return p;
-}
-
-void uiDrawFreePath(uiDrawPath *p)
-{
- g_array_free(p->pieces, TRUE);
- uiFree(p);
-}
-
-static void add(uiDrawPath *p, struct piece *piece)
-{
- if (p->ended)
- userbug("You cannot modify a uiDrawPath that has been ended. (path: %p)", p);
- g_array_append_vals(p->pieces, piece, 1);
-}
-
-void uiDrawPathNewFigure(uiDrawPath *p, double x, double y)
-{
- struct piece piece;
-
- piece.type = newFigure;
- piece.d[0] = x;
- piece.d[1] = y;
- add(p, &piece);
-}
-
-void uiDrawPathNewFigureWithArc(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
-{
- struct piece piece;
-
- if (sweep > 2 * uiPi)
- sweep = 2 * uiPi;
- piece.type = newFigureArc;
- piece.d[0] = xCenter;
- piece.d[1] = yCenter;
- piece.d[2] = radius;
- piece.d[3] = startAngle;
- piece.d[4] = sweep;
- piece.b = negative;
- add(p, &piece);
-}
-
-void uiDrawPathLineTo(uiDrawPath *p, double x, double y)
-{
- struct piece piece;
-
- piece.type = lineTo;
- piece.d[0] = x;
- piece.d[1] = y;
- add(p, &piece);
-}
-
-void uiDrawPathArcTo(uiDrawPath *p, double xCenter, double yCenter, double radius, double startAngle, double sweep, int negative)
-{
- struct piece piece;
-
- if (sweep > 2 * uiPi)
- sweep = 2 * uiPi;
- piece.type = arcTo;
- piece.d[0] = xCenter;
- piece.d[1] = yCenter;
- piece.d[2] = radius;
- piece.d[3] = startAngle;
- piece.d[4] = sweep;
- piece.b = negative;
- add(p, &piece);
-}
-
-void uiDrawPathBezierTo(uiDrawPath *p, double c1x, double c1y, double c2x, double c2y, double endX, double endY)
-{
- struct piece piece;
-
- piece.type = bezierTo;
- piece.d[0] = c1x;
- piece.d[1] = c1y;
- piece.d[2] = c2x;
- piece.d[3] = c2y;
- piece.d[4] = endX;
- piece.d[5] = endY;
- add(p, &piece);
-}
-
-void uiDrawPathCloseFigure(uiDrawPath *p)
-{
- struct piece piece;
-
- piece.type = closeFigure;
- add(p, &piece);
-}
-
-void uiDrawPathAddRectangle(uiDrawPath *p, double x, double y, double width, double height)
-{
- struct piece piece;
-
- piece.type = addRect;
- piece.d[0] = x;
- piece.d[1] = y;
- piece.d[2] = width;
- piece.d[3] = height;
- add(p, &piece);
-}
-
-void uiDrawPathEnd(uiDrawPath *p)
-{
- p->ended = TRUE;
-}
-
-void runPath(uiDrawPath *p, cairo_t *cr)
-{
- guint i;
- struct piece *piece;
- void (*arc)(cairo_t *, double, double, double, double, double);
-
- if (!p->ended)
- userbug("You cannot draw with a uiDrawPath that has not been ended. (path: %p)", p);
- cairo_new_path(cr);
- for (i = 0; i < p->pieces->len; i++) {
- piece = &g_array_index(p->pieces, struct piece, i);
- switch (piece->type) {
- case newFigure:
- cairo_move_to(cr, piece->d[0], piece->d[1]);
- break;
- case newFigureArc:
- cairo_new_sub_path(cr);
- // fall through
- case arcTo:
- arc = cairo_arc;
- if (piece->b)
- arc = cairo_arc_negative;
- (*arc)(cr,
- piece->d[0],
- piece->d[1],
- piece->d[2],
- piece->d[3],
- piece->d[3] + piece->d[4]);
- break;
- case lineTo:
- cairo_line_to(cr, piece->d[0], piece->d[1]);
- break;
- case bezierTo:
- cairo_curve_to(cr,
- piece->d[0],
- piece->d[1],
- piece->d[2],
- piece->d[3],
- piece->d[4],
- piece->d[5]);
- break;
- case closeFigure:
- cairo_close_path(cr);
- break;
- case addRect:
- cairo_rectangle(cr,
- piece->d[0],
- piece->d[1],
- piece->d[2],
- piece->d[3]);
- break;
- }
- }
-}
-
-uiDrawFillMode pathFillMode(uiDrawPath *path)
-{
- return path->fillMode;
-}
diff --git a/src/libui_sdl/libui/unix/drawtext.c b/src/libui_sdl/libui/unix/drawtext.c
deleted file mode 100644
index 7078e1a..0000000
--- a/src/libui_sdl/libui/unix/drawtext.c
+++ /dev/null
@@ -1,293 +0,0 @@
-// 6 september 2015
-#include "uipriv_unix.h"
-#include "draw.h"
-
-struct uiDrawFontFamilies {
- PangoFontFamily **f;
- int n;
-};
-
-uiDrawFontFamilies *uiDrawListFontFamilies(void)
-{
- uiDrawFontFamilies *ff;
- PangoFontMap *map;
-
- ff = uiNew(uiDrawFontFamilies);
- map = pango_cairo_font_map_get_default();
- pango_font_map_list_families(map, &(ff->f), &(ff->n));
- // do not free map; it's a shared resource
- return ff;
-}
-
-int uiDrawFontFamiliesNumFamilies(uiDrawFontFamilies *ff)
-{
- return ff->n;
-}
-
-char *uiDrawFontFamiliesFamily(uiDrawFontFamilies *ff, int n)
-{
- PangoFontFamily *f;
-
- f = ff->f[n];
- return uiUnixStrdupText(pango_font_family_get_name(f));
-}
-
-void uiDrawFreeFontFamilies(uiDrawFontFamilies *ff)
-{
- g_free(ff->f);
- uiFree(ff);
-}
-
-struct uiDrawTextFont {
- PangoFont *f;
-};
-
-uiDrawTextFont *mkTextFont(PangoFont *f, gboolean ref)
-{
- uiDrawTextFont *font;
-
- font = uiNew(uiDrawTextFont);
- font->f = f;
- if (ref)
- g_object_ref(font->f);
- return font;
-}
-
-static const PangoWeight pangoWeights[] = {
- [uiDrawTextWeightThin] = PANGO_WEIGHT_THIN,
- [uiDrawTextWeightUltraLight] = PANGO_WEIGHT_ULTRALIGHT,
- [uiDrawTextWeightLight] = PANGO_WEIGHT_LIGHT,
- [uiDrawTextWeightBook] = PANGO_WEIGHT_BOOK,
- [uiDrawTextWeightNormal] = PANGO_WEIGHT_NORMAL,
- [uiDrawTextWeightMedium] = PANGO_WEIGHT_MEDIUM,
- [uiDrawTextWeightSemiBold] = PANGO_WEIGHT_SEMIBOLD,
- [uiDrawTextWeightBold] = PANGO_WEIGHT_BOLD,
- [uiDrawTextWeightUltraBold] = PANGO_WEIGHT_ULTRABOLD,
- [uiDrawTextWeightHeavy] = PANGO_WEIGHT_HEAVY,
- [uiDrawTextWeightUltraHeavy] = PANGO_WEIGHT_ULTRAHEAVY,
-};
-
-static const PangoStyle pangoItalics[] = {
- [uiDrawTextItalicNormal] = PANGO_STYLE_NORMAL,
- [uiDrawTextItalicOblique] = PANGO_STYLE_OBLIQUE,
- [uiDrawTextItalicItalic] = PANGO_STYLE_ITALIC,
-};
-
-static const PangoStretch pangoStretches[] = {
- [uiDrawTextStretchUltraCondensed] = PANGO_STRETCH_ULTRA_CONDENSED,
- [uiDrawTextStretchExtraCondensed] = PANGO_STRETCH_EXTRA_CONDENSED,
- [uiDrawTextStretchCondensed] = PANGO_STRETCH_CONDENSED,
- [uiDrawTextStretchSemiCondensed] = PANGO_STRETCH_SEMI_CONDENSED,
- [uiDrawTextStretchNormal] = PANGO_STRETCH_NORMAL,
- [uiDrawTextStretchSemiExpanded] = PANGO_STRETCH_SEMI_EXPANDED,
- [uiDrawTextStretchExpanded] = PANGO_STRETCH_EXPANDED,
- [uiDrawTextStretchExtraExpanded] = PANGO_STRETCH_EXTRA_EXPANDED,
- [uiDrawTextStretchUltraExpanded] = PANGO_STRETCH_ULTRA_EXPANDED,
-};
-
-// we need a context for a few things
-// the documentation suggests creating cairo_t-specific, GdkScreen-specific, or even GtkWidget-specific contexts, but we can't really do that because we want our uiDrawTextFonts and uiDrawTextLayouts to be context-independent
-// we could use pango_font_map_create_context(pango_cairo_font_map_get_default()) but that will ignore GDK-specific settings
-// so let's use gdk_pango_context_get() instead; even though it's for the default screen only, it's good enough for us
-#define mkGenericPangoCairoContext() (gdk_pango_context_get())
-
-PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc)
-{
- PangoFont *f;
- PangoContext *context;
-
- // in this case, the context is necessary for the metrics to be correct
- context = mkGenericPangoCairoContext();
- f = pango_font_map_load_font(pango_cairo_font_map_get_default(), context, pdesc);
- if (f == NULL) {
- // LONGTERM
- g_error("[libui] no match in pangoDescToPangoFont(); report to andlabs");
- }
- g_object_unref(context);
- return f;
-}
-
-uiDrawTextFont *uiDrawLoadClosestFont(const uiDrawTextFontDescriptor *desc)
-{
- PangoFont *f;
- PangoFontDescription *pdesc;
-
- pdesc = pango_font_description_new();
- pango_font_description_set_family(pdesc,
- desc->Family);
- pango_font_description_set_size(pdesc,
- (gint) (desc->Size * PANGO_SCALE));
- pango_font_description_set_weight(pdesc,
- pangoWeights[desc->Weight]);
- pango_font_description_set_style(pdesc,
- pangoItalics[desc->Italic]);
- pango_font_description_set_stretch(pdesc,
- pangoStretches[desc->Stretch]);
- f = pangoDescToPangoFont(pdesc);
- pango_font_description_free(pdesc);
- return mkTextFont(f, FALSE); // we hold the initial reference; no need to ref
-}
-
-void uiDrawFreeTextFont(uiDrawTextFont *font)
-{
- g_object_unref(font->f);
- uiFree(font);
-}
-
-uintptr_t uiDrawTextFontHandle(uiDrawTextFont *font)
-{
- return (uintptr_t) (font->f);
-}
-
-void uiDrawTextFontDescribe(uiDrawTextFont *font, uiDrawTextFontDescriptor *desc)
-{
- PangoFontDescription *pdesc;
-
- // this creates a copy; we free it later
- pdesc = pango_font_describe(font->f);
-
- // TODO
-
- pango_font_description_free(pdesc);
-}
-
-// See https://developer.gnome.org/pango/1.30/pango-Cairo-Rendering.html#pango-Cairo-Rendering.description
-// Note that we convert to double before dividing to make sure the floating-point stuff is right
-#define pangoToCairo(pango) (((double) (pango)) / PANGO_SCALE)
-#define cairoToPango(cairo) ((gint) ((cairo) * PANGO_SCALE))
-
-void uiDrawTextFontGetMetrics(uiDrawTextFont *font, uiDrawTextFontMetrics *metrics)
-{
- PangoFontMetrics *pm;
-
- pm = pango_font_get_metrics(font->f, NULL);
- metrics->Ascent = pangoToCairo(pango_font_metrics_get_ascent(pm));
- metrics->Descent = pangoToCairo(pango_font_metrics_get_descent(pm));
- // Pango doesn't seem to expose this :( Use 0 and hope for the best.
- metrics->Leading = 0;
- metrics->UnderlinePos = pangoToCairo(pango_font_metrics_get_underline_position(pm));
- metrics->UnderlineThickness = pangoToCairo(pango_font_metrics_get_underline_thickness(pm));
- pango_font_metrics_unref(pm);
-}
-
-// note: PangoCairoLayouts are tied to a given cairo_t, so we can't store one in this device-independent structure
-struct uiDrawTextLayout {
- char *s;
- ptrdiff_t *graphemes;
- PangoFont *defaultFont;
- double width;
- PangoAttrList *attrs;
-};
-
-uiDrawTextLayout *uiDrawNewTextLayout(const char *text, uiDrawTextFont *defaultFont, double width)
-{
- uiDrawTextLayout *layout;
- PangoContext *context;
-
- layout = uiNew(uiDrawTextLayout);
- layout->s = g_strdup(text);
- context = mkGenericPangoCairoContext();
- layout->graphemes = graphemes(layout->s, context);
- g_object_unref(context);
- layout->defaultFont = defaultFont->f;
- g_object_ref(layout->defaultFont); // retain a copy
- uiDrawTextLayoutSetWidth(layout, width);
- layout->attrs = pango_attr_list_new();
- return layout;
-}
-
-void uiDrawFreeTextLayout(uiDrawTextLayout *layout)
-{
- pango_attr_list_unref(layout->attrs);
- g_object_unref(layout->defaultFont);
- uiFree(layout->graphemes);
- g_free(layout->s);
- uiFree(layout);
-}
-
-void uiDrawTextLayoutSetWidth(uiDrawTextLayout *layout, double width)
-{
- layout->width = width;
-}
-
-static void prepareLayout(uiDrawTextLayout *layout, PangoLayout *pl)
-{
- PangoFontDescription *desc;
- int width;
-
- pango_layout_set_text(pl, layout->s, -1);
-
- // again, this makes a copy
- desc = pango_font_describe(layout->defaultFont);
- // this is safe; the description is copied
- pango_layout_set_font_description(pl, desc);
- pango_font_description_free(desc);
-
- width = cairoToPango(layout->width);
- if (layout->width < 0)
- width = -1;
- pango_layout_set_width(pl, width);
-
- pango_layout_set_attributes(pl, layout->attrs);
-}
-
-void uiDrawTextLayoutExtents(uiDrawTextLayout *layout, double *width, double *height)
-{
- PangoContext *context;
- PangoLayout *pl;
- PangoRectangle logical;
-
- // in this case, the context is necessary to create the layout
- // the layout takes a ref on the context so we can unref it afterward
- context = mkGenericPangoCairoContext();
- pl = pango_layout_new(context);
- g_object_unref(context);
- prepareLayout(layout, pl);
-
- pango_layout_get_extents(pl, NULL, &logical);
-
- g_object_unref(pl);
-
- *width = pangoToCairo(logical.width);
- *height = pangoToCairo(logical.height);
-}
-
-void uiDrawText(uiDrawContext *c, double x, double y, uiDrawTextLayout *layout)
-{
- PangoLayout *pl;
-
- pl = pango_cairo_create_layout(c->cr);
- prepareLayout(layout, pl);
-
- cairo_move_to(c->cr, x, y);
- pango_cairo_show_layout(c->cr, pl);
-
- g_object_unref(pl);
-}
-
-static void addAttr(uiDrawTextLayout *layout, PangoAttribute *attr, int startChar, int endChar)
-{
- attr->start_index = layout->graphemes[startChar];
- attr->end_index = layout->graphemes[endChar];
- pango_attr_list_insert(layout->attrs, attr);
- // pango_attr_list_insert() takes attr; we don't free it
-}
-
-void uiDrawTextLayoutSetColor(uiDrawTextLayout *layout, int startChar, int endChar, double r, double g, double b, double a)
-{
- PangoAttribute *attr;
- guint16 rr, gg, bb, aa;
-
- rr = (guint16) (r * 65535);
- gg = (guint16) (g * 65535);
- bb = (guint16) (b * 65535);
- aa = (guint16) (a * 65535);
-
- attr = pango_attr_foreground_new(rr, gg, bb);
- addAttr(layout, attr, startChar, endChar);
-
- // TODO what if aa == 0?
- attr = FUTURE_pango_attr_foreground_alpha_new(aa);
- if (attr != NULL)
- addAttr(layout, attr, startChar, endChar);
-}
diff --git a/src/libui_sdl/libui/unix/editablecombo.c b/src/libui_sdl/libui/unix/editablecombo.c
deleted file mode 100644
index 7ee3829..0000000
--- a/src/libui_sdl/libui/unix/editablecombo.c
+++ /dev/null
@@ -1,79 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiEditableCombobox {
- uiUnixControl c;
- GtkWidget *widget;
- GtkBin *bin;
- GtkComboBox *combobox;
- GtkComboBoxText *comboboxText;
- void (*onChanged)(uiEditableCombobox *, void *);
- void *onChangedData;
- gulong onChangedSignal;
-};
-
-uiUnixControlAllDefaults(uiEditableCombobox)
-
-static void onChanged(GtkComboBox *cbox, gpointer data)
-{
- uiEditableCombobox *c = uiEditableCombobox(data);
-
- (*(c->onChanged))(c, c->onChangedData);
-}
-
-static void defaultOnChanged(uiEditableCombobox *c, void *data)
-{
- // do nothing
-}
-
-void uiEditableComboboxAppend(uiEditableCombobox *c, const char *text)
-{
- gtk_combo_box_text_append(c->comboboxText, NULL, text);
-}
-
-char *uiEditableComboboxText(uiEditableCombobox *c)
-{
- char *s;
- char *out;
-
- s = gtk_combo_box_text_get_active_text(c->comboboxText);
- // s will always be non-NULL in the case of a combobox with an entry (according to the source code)
- out = uiUnixStrdupText(s);
- g_free(s);
- return out;
-}
-
-void uiEditableComboboxSetText(uiEditableCombobox *c, const char *text)
-{
- GtkEntry *e;
-
- // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
- g_signal_handler_block(c->combobox, c->onChangedSignal);
- // since there isn't a gtk_combo_box_text_set_active_text()...
- e = GTK_ENTRY(gtk_bin_get_child(c->bin));
- gtk_entry_set_text(e, text);
- g_signal_handler_unblock(c->combobox, c->onChangedSignal);
-}
-
-void uiEditableComboboxOnChanged(uiEditableCombobox *c, void (*f)(uiEditableCombobox *c, void *data), void *data)
-{
- c->onChanged = f;
- c->onChangedData = data;
-}
-
-uiEditableCombobox *uiNewEditableCombobox(void)
-{
- uiEditableCombobox *c;
-
- uiUnixNewControl(uiEditableCombobox, c);
-
- c->widget = gtk_combo_box_text_new_with_entry();
- c->bin = GTK_BIN(c->widget);
- c->combobox = GTK_COMBO_BOX(c->widget);
- c->comboboxText = GTK_COMBO_BOX_TEXT(c->widget);
-
- c->onChangedSignal = g_signal_connect(c->widget, "changed", G_CALLBACK(onChanged), c);
- uiEditableComboboxOnChanged(c, defaultOnChanged, NULL);
-
- return c;
-}
diff --git a/src/libui_sdl/libui/unix/entry.c b/src/libui_sdl/libui/unix/entry.c
deleted file mode 100644
index 4a9a1d0..0000000
--- a/src/libui_sdl/libui/unix/entry.c
+++ /dev/null
@@ -1,97 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiEntry {
- uiUnixControl c;
- GtkWidget *widget;
- GtkEntry *entry;
- GtkEditable *editable;
- void (*onChanged)(uiEntry *, void *);
- void *onChangedData;
- gulong onChangedSignal;
-};
-
-uiUnixControlAllDefaults(uiEntry)
-
-static void onChanged(GtkEditable *editable, gpointer data)
-{
- uiEntry *e = uiEntry(data);
-
- (*(e->onChanged))(e, e->onChangedData);
-}
-
-static void defaultOnChanged(uiEntry *e, void *data)
-{
- // do nothing
-}
-
-char *uiEntryText(uiEntry *e)
-{
- return uiUnixStrdupText(gtk_entry_get_text(e->entry));
-}
-
-void uiEntrySetText(uiEntry *e, const char *text)
-{
- // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
- g_signal_handler_block(e->editable, e->onChangedSignal);
- gtk_entry_set_text(e->entry, text);
- g_signal_handler_unblock(e->editable, e->onChangedSignal);
- // don't queue the control for resize; entry sizes are independent of their contents
-}
-
-void uiEntryOnChanged(uiEntry *e, void (*f)(uiEntry *, void *), void *data)
-{
- e->onChanged = f;
- e->onChangedData = data;
-}
-
-int uiEntryReadOnly(uiEntry *e)
-{
- return gtk_editable_get_editable(e->editable) == FALSE;
-}
-
-void uiEntrySetReadOnly(uiEntry *e, int readonly)
-{
- gboolean editable;
-
- editable = TRUE;
- if (readonly)
- editable = FALSE;
- gtk_editable_set_editable(e->editable, editable);
-}
-
-static uiEntry *finishNewEntry(GtkWidget *w, const gchar *signal)
-{
- uiEntry *e;
-
- uiUnixNewControl(uiEntry, e);
-
- e->widget = w;
- e->entry = GTK_ENTRY(e->widget);
- e->editable = GTK_EDITABLE(e->widget);
-
- e->onChangedSignal = g_signal_connect(e->widget, signal, G_CALLBACK(onChanged), e);
- uiEntryOnChanged(e, defaultOnChanged, NULL);
-
- return e;
-}
-
-uiEntry *uiNewEntry(void)
-{
- return finishNewEntry(gtk_entry_new(), "changed");
-}
-
-uiEntry *uiNewPasswordEntry(void)
-{
- GtkWidget *e;
-
- e = gtk_entry_new();
- gtk_entry_set_visibility(GTK_ENTRY(e), FALSE);
- return finishNewEntry(e, "changed");
-}
-
-// TODO make it use a separate function to be type-safe
-uiEntry *uiNewSearchEntry(void)
-{
- return finishNewEntry(gtk_search_entry_new(), "search-changed");
-}
diff --git a/src/libui_sdl/libui/unix/fontbutton.c b/src/libui_sdl/libui/unix/fontbutton.c
deleted file mode 100644
index f8047e0..0000000
--- a/src/libui_sdl/libui/unix/fontbutton.c
+++ /dev/null
@@ -1,70 +0,0 @@
-// 14 april 2016
-#include "uipriv_unix.h"
-
-struct uiFontButton {
- uiUnixControl c;
- GtkWidget *widget;
- GtkButton *button;
- GtkFontButton *fb;
- GtkFontChooser *fc;
- void (*onChanged)(uiFontButton *, void *);
- void *onChangedData;
-};
-
-uiUnixControlAllDefaults(uiFontButton)
-
-// TODO NOTE no need to inhibit the signal; font-set is documented as only being sent when the user changes the font
-static void onFontSet(GtkFontButton *button, gpointer data)
-{
- uiFontButton *b = uiFontButton(data);
-
- (*(b->onChanged))(b, b->onChangedData);
-}
-
-static void defaultOnChanged(uiFontButton *b, void *data)
-{
- // do nothing
-}
-
-uiDrawTextFont *uiFontButtonFont(uiFontButton *b)
-{
- PangoFont *f;
- PangoFontDescription *desc;
-
- desc = gtk_font_chooser_get_font_desc(b->fc);
- f = pangoDescToPangoFont(desc);
- // desc is transfer-full and thus is a copy
- pango_font_description_free(desc);
- return mkTextFont(f, FALSE); // we hold the initial reference; no need to ref
-}
-
-void uiFontButtonOnChanged(uiFontButton *b, void (*f)(uiFontButton *, void *), void *data)
-{
- b->onChanged = f;
- b->onChangedData = data;
-}
-
-uiFontButton *uiNewFontButton(void)
-{
- uiFontButton *b;
-
- uiUnixNewControl(uiFontButton, b);
-
- b->widget = gtk_font_button_new();
- b->button = GTK_BUTTON(b->widget);
- b->fb = GTK_FONT_BUTTON(b->widget);
- b->fc = GTK_FONT_CHOOSER(b->widget);
-
- // match behavior on other platforms
- gtk_font_button_set_show_style(b->fb, TRUE);
- gtk_font_button_set_show_size(b->fb, TRUE);
- gtk_font_button_set_use_font(b->fb, FALSE);
- gtk_font_button_set_use_size(b->fb, FALSE);
- // other customizations
- gtk_font_chooser_set_show_preview_entry(b->fc, TRUE);
-
- g_signal_connect(b->widget, "font-set", G_CALLBACK(onFontSet), b);
- uiFontButtonOnChanged(b, defaultOnChanged, NULL);
-
- return b;
-}
diff --git a/src/libui_sdl/libui/unix/form.c b/src/libui_sdl/libui/unix/form.c
deleted file mode 100644
index 54422b3..0000000
--- a/src/libui_sdl/libui/unix/form.c
+++ /dev/null
@@ -1,159 +0,0 @@
-// 8 june 2016
-#include "uipriv_unix.h"
-
-struct formChild {
- uiControl *c;
- int stretchy;
- GtkWidget *label;
- gboolean oldhexpand;
- GtkAlign oldhalign;
- gboolean oldvexpand;
- GtkAlign oldvalign;
- GBinding *labelBinding;
-};
-
-struct uiForm {
- uiUnixControl c;
- GtkWidget *widget;
- GtkContainer *container;
- GtkGrid *grid;
- GArray *children;
- int padded;
- GtkSizeGroup *stretchygroup; // ensures all stretchy controls have the same size
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiForm)
-
-#define ctrl(f, i) &g_array_index(f->children, struct formChild, i)
-
-static void uiFormDestroy(uiControl *c)
-{
- uiForm *f = uiForm(c);
- struct formChild *fc;
- guint i;
-
- // kill the size group
- g_object_unref(f->stretchygroup);
- // free all controls
- for (i = 0; i < f->children->len; i++) {
- fc = ctrl(f, i);
- uiControlSetParent(fc->c, NULL);
- uiUnixControlSetContainer(uiUnixControl(fc->c), f->container, TRUE);
- uiControlDestroy(fc->c);
- gtk_widget_destroy(fc->label);
- }
- g_array_free(f->children, TRUE);
- // and then ourselves
- g_object_unref(f->widget);
- uiFreeControl(uiControl(f));
-}
-
-void uiFormAppend(uiForm *f, const char *label, uiControl *c, int stretchy)
-{
- struct formChild fc;
- GtkWidget *widget;
- guint row;
-
- fc.c = c;
- widget = GTK_WIDGET(uiControlHandle(fc.c));
- fc.stretchy = stretchy;
- fc.oldhexpand = gtk_widget_get_hexpand(widget);
- fc.oldhalign = gtk_widget_get_halign(widget);
- fc.oldvexpand = gtk_widget_get_vexpand(widget);
- fc.oldvalign = gtk_widget_get_valign(widget);
-
- if (stretchy) {
- gtk_widget_set_vexpand(widget, TRUE);
- gtk_widget_set_valign(widget, GTK_ALIGN_FILL);
- gtk_size_group_add_widget(f->stretchygroup, widget);
- } else
- gtk_widget_set_vexpand(widget, FALSE);
- // and make them fill horizontally
- gtk_widget_set_hexpand(widget, TRUE);
- gtk_widget_set_halign(widget, GTK_ALIGN_FILL);
-
- fc.label = gtk_label_new(label);
- gtk_widget_set_hexpand(fc.label, FALSE);
- gtk_widget_set_halign(fc.label, GTK_ALIGN_END);
- gtk_widget_set_vexpand(fc.label, FALSE);
- if (GTK_IS_SCROLLED_WINDOW(widget))
- gtk_widget_set_valign(fc.label, GTK_ALIGN_START);
- else
- gtk_widget_set_valign(fc.label, GTK_ALIGN_CENTER);
- gtk_style_context_add_class(gtk_widget_get_style_context(fc.label), "dim-label");
- row = f->children->len;
- gtk_grid_attach(f->grid, fc.label,
- 0, row,
- 1, 1);
- // and make them share visibility so if the control is hidden, so is its label
- fc.labelBinding = g_object_bind_property(GTK_WIDGET(uiControlHandle(fc.c)), "visible",
- fc.label, "visible",
- G_BINDING_SYNC_CREATE);
-
- uiControlSetParent(fc.c, uiControl(f));
- uiUnixControlSetContainer(uiUnixControl(fc.c), f->container, FALSE);
- g_array_append_val(f->children, fc);
-
- // move the widget to the correct place
- gtk_container_child_set(f->container, widget,
- "left-attach", 1,
- "top-attach", row,
- NULL);
-}
-
-void uiFormDelete(uiForm *f, int index)
-{
- struct formChild *fc;
- GtkWidget *widget;
-
- fc = ctrl(f, index);
- widget = GTK_WIDGET(uiControlHandle(fc->c));
-
- gtk_widget_destroy(fc->label);
-
- uiControlSetParent(fc->c, NULL);
- uiUnixControlSetContainer(uiUnixControl(fc->c), f->container, TRUE);
-
- if (fc->stretchy)
- gtk_size_group_remove_widget(f->stretchygroup, widget);
- gtk_widget_set_hexpand(widget, fc->oldhexpand);
- gtk_widget_set_halign(widget, fc->oldhalign);
- gtk_widget_set_vexpand(widget, fc->oldvexpand);
- gtk_widget_set_valign(widget, fc->oldvalign);
-
- g_array_remove_index(f->children, index);
-}
-
-int uiFormPadded(uiForm *f)
-{
- return f->padded;
-}
-
-void uiFormSetPadded(uiForm *f, int padded)
-{
- f->padded = padded;
- if (f->padded) {
- gtk_grid_set_row_spacing(f->grid, gtkYPadding);
- gtk_grid_set_column_spacing(f->grid, gtkXPadding);
- } else {
- gtk_grid_set_row_spacing(f->grid, 0);
- gtk_grid_set_column_spacing(f->grid, 0);
- }
-}
-
-uiForm *uiNewForm(void)
-{
- uiForm *f;
-
- uiUnixNewControl(uiForm, f);
-
- f->widget = gtk_grid_new();
- f->container = GTK_CONTAINER(f->widget);
- f->grid = GTK_GRID(f->widget);
-
- f->stretchygroup = gtk_size_group_new(GTK_SIZE_GROUP_VERTICAL);
-
- f->children = g_array_new(FALSE, TRUE, sizeof (struct formChild));
-
- return f;
-}
diff --git a/src/libui_sdl/libui/unix/future.c b/src/libui_sdl/libui/unix/future.c
deleted file mode 100644
index 1f9f532..0000000
--- a/src/libui_sdl/libui/unix/future.c
+++ /dev/null
@@ -1,42 +0,0 @@
-// 29 june 2016
-#include "uipriv_unix.h"
-
-// functions FROM THE FUTURE!
-// in some cases, because being held back by LTS releases sucks :/
-// in others, because parts of GTK+ being unstable until recently also sucks :/
-
-// added in pango 1.38; we need 1.36
-static PangoAttribute *(*newFGAlphaAttr)(guint16 alpha) = NULL;
-
-// added in GTK+ 3.20; we need 3.10
-static void (*gwpIterSetObjectName)(GtkWidgetPath *path, gint pos, const char *name) = NULL;
-
-// note that we treat any error as "the symbols aren't there" (and don't care if dlclose() failed)
-void loadFutures(void)
-{
- void *handle;
-
- // dlsym() walks the dependency chain, so opening the current process should be sufficient
- handle = dlopen(NULL, RTLD_LAZY);
- if (handle == NULL)
- return;
-#define GET(var, fn) *((void **) (&var)) = dlsym(handle, #fn)
- GET(newFGAlphaAttr, pango_attr_foreground_alpha_new);
- GET(gwpIterSetObjectName, gtk_widget_path_iter_set_object_name);
- dlclose(handle);
-}
-
-PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha)
-{
- if (newFGAlphaAttr == NULL)
- return NULL;
- return (*newFGAlphaAttr)(alpha);
-}
-
-gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name)
-{
- if (gwpIterSetObjectName == NULL)
- return FALSE;
- (*gwpIterSetObjectName)(path, pos, name);
- return TRUE;
-}
diff --git a/src/libui_sdl/libui/unix/gl.c b/src/libui_sdl/libui/unix/gl.c
deleted file mode 100644
index e15cf4f..0000000
--- a/src/libui_sdl/libui/unix/gl.c
+++ /dev/null
@@ -1,251 +0,0 @@
-// 26 may 2019
-#include "uipriv_unix.h"
-
-#include <GL/gl.h>
-#include <GL/glx.h>
-#include <EGL/egl.h>
-
-extern GThread* gtkthread;
-extern GMutex glmutex;
-
-struct uiGLContext
-{
- GtkWidget* widget;
- GdkWindow* window;
-
- GdkGLContext *gctx;
- int vermaj, vermin;
-
- int width, height;
- int scale;
- GLuint renderbuffer[2][2];
- GLuint framebuffer[2];
- int backbuffer;
-};
-
-static void areaAllocRenderbuffer(uiGLContext* glctx);
-
-static PFNGLGENRENDERBUFFERSPROC _glGenRenderbuffers;
-static PFNGLDELETERENDERBUFFERSPROC _glDeleteRenderbuffers;
-static PFNGLBINDRENDERBUFFERPROC _glBindRenderbuffer;
-static PFNGLRENDERBUFFERSTORAGEPROC _glRenderbufferStorage;
-static PFNGLGETRENDERBUFFERPARAMETERIVPROC _glGetRenderbufferParameteriv;
-
-static PFNGLGENRENDERBUFFERSPROC _glGenFramebuffers;
-static PFNGLDELETERENDERBUFFERSPROC _glDeleteFramebuffers;
-static PFNGLBINDRENDERBUFFERPROC _glBindFramebuffer;
-static PFNGLFRAMEBUFFERTEXTUREPROC _glFramebufferTexture;
-static PFNGLFRAMEBUFFERRENDERBUFFERPROC _glFramebufferRenderbuffer;
-static PFNGLCHECKFRAMEBUFFERSTATUSPROC _glCheckFramebufferStatus;
-
-static int _procsLoaded = 0;
-
-static void _loadGLProcs(GdkGLContext* glctx)
-{
- if (_procsLoaded) return;
-
- _glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)uiGLGetProcAddress("glGenRenderbuffers");
- _glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)uiGLGetProcAddress("glDeleteRenderbuffers");
- _glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)uiGLGetProcAddress("glBindRenderbuffer");
- _glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)uiGLGetProcAddress("glRenderbufferStorage");
- _glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)uiGLGetProcAddress("glGetRenderbufferParameteriv");
-
- _glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)uiGLGetProcAddress("glGenFramebuffers");
- _glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)uiGLGetProcAddress("glDeleteFramebuffers");
- _glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)uiGLGetProcAddress("glBindFramebuffer");
- _glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)uiGLGetProcAddress("glFramebufferTexture");
- _glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)uiGLGetProcAddress("glFramebufferRenderbuffer");
- _glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)uiGLGetProcAddress("glCheckFramebufferStatus");
-
- _procsLoaded = 1;
-}
-
-uiGLContext *createGLContext(GtkWidget* widget, int maj, int min)
-{
- GdkWindow* gdkwin = gtk_widget_get_window(widget);
-
- GError* err = NULL;
- GdkGLContext* gctx = gdk_window_create_gl_context(gdkwin, &err);
- if (err != NULL || gctx == NULL)
- {
- return NULL;
- }
-
- // TODO: make the set_use_es call conditional (#ifdef or smth) for older versions of gdk?
- gdk_gl_context_set_use_es(gctx, FALSE);
- gdk_gl_context_set_required_version(gctx, maj, min);
-
- gboolean res = gdk_gl_context_realize(gctx, &err);
- if (err != NULL || res == FALSE)
- {
- return NULL;
- }
-
- uiGLContext* ctx = uiNew(uiGLContext);
-
- GtkAllocation allocation;
- gtk_widget_get_allocation(widget, &allocation);
- int window_scale = gdk_window_get_scale_factor(gdkwin);
- ctx->width = allocation.width;
- ctx->height = allocation.height;
- ctx->scale = window_scale;
-
- gdk_gl_context_make_current(gctx);
- _loadGLProcs(gctx);
- areaAllocRenderbuffer(ctx);
- ctx->backbuffer = 0;
-
- ctx->widget = widget;
- ctx->window = gdkwin;
- ctx->gctx = gctx;
-
- return ctx;
-}
-
-void freeGLContext(uiGLContext* glctx)
-{
- if (glctx == NULL) return;
-
- gdk_gl_context_make_current(glctx->gctx);
- _glDeleteRenderbuffers(4, &glctx->renderbuffer[0][0]);
- _glDeleteFramebuffers(2, &glctx->framebuffer[0]);
-
- gdk_gl_context_clear_current();
- g_object_unref(glctx->gctx);
- uiFree(glctx);
-}
-
-static void areaAllocRenderbuffer(uiGLContext* glctx)
-{
- // TODO: create textures as a fallback if GL_RGB renderbuffer isn't supported?
- // they say GL implementations aren't required to support a GL_RGB renderbuffer
- // however, a GL_RGBA one would cause gdk_cairo_draw_from_gl() to fall back to glReadPixels()
-
- _glGenRenderbuffers(4, &glctx->renderbuffer[0][0]);
- _glGenFramebuffers(2, &glctx->framebuffer[0]);
-
- _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
- _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
- //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
- //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
-
- _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[0]);
- _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
- _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
-
- _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
- _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
- //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
- //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
-
- _glBindFramebuffer(GL_FRAMEBUFFER, glctx->framebuffer[1]);
- _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
- _glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
-
- //if (_glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- // printf("FRAMEBUFFER IS BAD!! %04X\n", _glCheckFramebufferStatus(GL_FRAMEBUFFER));
-}
-
-static void areaReallocRenderbuffer(uiGLContext* glctx)
-{
- _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][0]);
- _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
- //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[0][1]);
- //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
-
- _glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][0]);
- _glRenderbufferStorage(GL_RENDERBUFFER, GL_RGB, glctx->width*glctx->scale, glctx->height*glctx->scale);
- //_glBindRenderbuffer(GL_RENDERBUFFER, glctx->renderbuffer[1][1]);
- //_glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL, glctx->width*glctx->scale, glctx->height*glctx->scale);
-}
-
-void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx)
-{
- int window_scale = gdk_window_get_scale_factor(glctx->window);
-
- if (glctx->width != dp->AreaWidth || glctx->height != dp->AreaHeight || glctx->scale != window_scale)
- {
- glctx->width = dp->AreaWidth;
- glctx->height = dp->AreaHeight;
- glctx->scale = window_scale;
- areaReallocRenderbuffer(glctx);
- }
- else
- {
- gdk_cairo_draw_from_gl(cr, gtk_widget_get_window(widget),
- glctx->renderbuffer[glctx->backbuffer][0], GL_RENDERBUFFER,
- 1, 0, 0, glctx->width*glctx->scale, glctx->height*glctx->scale);
- }
-}
-
-int uiGLGetFramebuffer(uiGLContext* ctx)
-{
- return ctx->framebuffer[ctx->backbuffer];
-}
-
-float uiGLGetFramebufferScale(uiGLContext* ctx)
-{
- return (float)ctx->scale;
-}
-
-void uiGLSwapBuffers(uiGLContext* ctx)
-{
- ctx->backbuffer = ctx->backbuffer ? 0 : 1;
-}
-
-void uiGLSetVSync(int sync)
-{
- // TODO
-}
-
-void uiGLMakeContextCurrent(uiGLContext* ctx)
-{
- if (!ctx)
- {
- gdk_gl_context_clear_current();
- return;
- }
-
- if (ctx->gctx == gdk_gl_context_get_current()) return;
- gdk_gl_context_make_current(ctx->gctx);
-}
-
-void uiGLBegin(uiGLContext* ctx)
-{
- if (g_thread_self() != gtkthread)
- {
- g_mutex_lock(&glmutex);
- }
-}
-
-void uiGLEnd(uiGLContext* ctx)
-{
- if (g_thread_self() != gtkthread)
- {
- g_mutex_unlock(&glmutex);
- }
-}
-
-void *uiGLGetProcAddress(const char* proc)
-{
- // TODO: consider using epoxy or something funny
-
- void* ptr;
-
- ptr = glXGetProcAddressARB((const GLubyte*)proc);
- if (ptr) return ptr;
-
- ptr = eglGetProcAddress(proc);
- if (ptr) return ptr;
-
- ptr = dlsym(NULL /* RTLD_DEFAULT */, proc);
- if (ptr) return ptr;
-
- return NULL;
-}
-unsigned int uiGLGetVersion(uiGLContext* ctx)
-{
- if (!ctx) return 0;
- return uiGLVersion(ctx->vermaj, ctx->vermin);
-}
-
diff --git a/src/libui_sdl/libui/unix/graphemes.c b/src/libui_sdl/libui/unix/graphemes.c
deleted file mode 100644
index a2c47b7..0000000
--- a/src/libui_sdl/libui/unix/graphemes.c
+++ /dev/null
@@ -1,31 +0,0 @@
-// 25 may 2016
-#include "uipriv_unix.h"
-
-ptrdiff_t *graphemes(const char *text, PangoContext *context)
-{
- size_t len, lenchars;
- PangoLogAttr *logattrs;
- ptrdiff_t *out;
- ptrdiff_t *op;
- size_t i;
-
- len = strlen(text);
- lenchars = g_utf8_strlen(text, -1);
- logattrs = (PangoLogAttr *) uiAlloc((lenchars + 1) * sizeof (PangoLogAttr), "PangoLogAttr[]");
- pango_get_log_attrs(text, len,
- -1, NULL,
- logattrs, lenchars + 1);
-
- // should be more than enough
- out = (ptrdiff_t *) uiAlloc((lenchars + 2) * sizeof (ptrdiff_t), "ptrdiff_t[]");
- op = out;
- for (i = 0; i < lenchars; i++)
- if (logattrs[i].is_cursor_position != 0)
- // TODO optimize this
- *op++ = g_utf8_offset_to_pointer(text, i) - text;
- // and do the last one
- *op++ = len;
-
- uiFree(logattrs);
- return out;
-}
diff --git a/src/libui_sdl/libui/unix/grid.c b/src/libui_sdl/libui/unix/grid.c
deleted file mode 100644
index 6d9813b..0000000
--- a/src/libui_sdl/libui/unix/grid.c
+++ /dev/null
@@ -1,141 +0,0 @@
-// 9 june 2016
-#include "uipriv_unix.h"
-
-struct gridChild {
- uiControl *c;
- GtkWidget *label;
- gboolean oldhexpand;
- GtkAlign oldhalign;
- gboolean oldvexpand;
- GtkAlign oldvalign;
-};
-
-struct uiGrid {
- uiUnixControl c;
- GtkWidget *widget;
- GtkContainer *container;
- GtkGrid *grid;
- GArray *children;
- int padded;
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiGrid)
-
-#define ctrl(g, i) &g_array_index(g->children, struct gridChild, i)
-
-static void uiGridDestroy(uiControl *c)
-{
- uiGrid *g = uiGrid(c);
- struct gridChild *gc;
- guint i;
-
- // free all controls
- for (i = 0; i < g->children->len; i++) {
- gc = ctrl(g, i);
- uiControlSetParent(gc->c, NULL);
- uiUnixControlSetContainer(uiUnixControl(gc->c), g->container, TRUE);
- uiControlDestroy(gc->c);
- }
- g_array_free(g->children, TRUE);
- // and then ourselves
- g_object_unref(g->widget);
- uiFreeControl(uiControl(g));
-}
-
-#define TODO_MASSIVE_HACK(c) \
- if (!uiUnixControl(c)->addedBefore) { \
- g_object_ref_sink(GTK_WIDGET(uiControlHandle(uiControl(c)))); \
- gtk_widget_show(GTK_WIDGET(uiControlHandle(uiControl(c)))); \
- uiUnixControl(c)->addedBefore = TRUE; \
- }
-
-static const GtkAlign gtkAligns[] = {
- [uiAlignFill] = GTK_ALIGN_FILL,
- [uiAlignStart] = GTK_ALIGN_START,
- [uiAlignCenter] = GTK_ALIGN_CENTER,
- [uiAlignEnd] = GTK_ALIGN_END,
-};
-
-static const GtkPositionType gtkPositions[] = {
- [uiAtLeading] = GTK_POS_LEFT,
- [uiAtTop] = GTK_POS_TOP,
- [uiAtTrailing] = GTK_POS_RIGHT,
- [uiAtBottom] = GTK_POS_BOTTOM,
-};
-
-static GtkWidget *prepare(struct gridChild *gc, uiControl *c, int hexpand, uiAlign halign, int vexpand, uiAlign valign)
-{
- GtkWidget *widget;
-
- gc->c = c;
- widget = GTK_WIDGET(uiControlHandle(gc->c));
- gc->oldhexpand = gtk_widget_get_hexpand(widget);
- gc->oldhalign = gtk_widget_get_halign(widget);
- gc->oldvexpand = gtk_widget_get_vexpand(widget);
- gc->oldvalign = gtk_widget_get_valign(widget);
- gtk_widget_set_hexpand(widget, hexpand != 0);
- gtk_widget_set_halign(widget, gtkAligns[halign]);
- gtk_widget_set_vexpand(widget, vexpand != 0);
- gtk_widget_set_valign(widget, gtkAligns[valign]);
- return widget;
-}
-
-void uiGridAppend(uiGrid *g, uiControl *c, int left, int top, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign)
-{
- struct gridChild gc;
- GtkWidget *widget;
-
- widget = prepare(&gc, c, hexpand, halign, vexpand, valign);
- uiControlSetParent(gc.c, uiControl(g));
- TODO_MASSIVE_HACK(uiUnixControl(gc.c));
- gtk_grid_attach(g->grid, widget,
- left, top,
- xspan, yspan);
- g_array_append_val(g->children, gc);
-}
-
-void uiGridInsertAt(uiGrid *g, uiControl *c, uiControl *existing, uiAt at, int xspan, int yspan, int hexpand, uiAlign halign, int vexpand, uiAlign valign)
-{
- struct gridChild gc;
- GtkWidget *widget;
-
- widget = prepare(&gc, c, hexpand, halign, vexpand, valign);
- uiControlSetParent(gc.c, uiControl(g));
- TODO_MASSIVE_HACK(uiUnixControl(gc.c));
- gtk_grid_attach_next_to(g->grid, widget,
- GTK_WIDGET(uiControlHandle(existing)), gtkPositions[at],
- xspan, yspan);
- g_array_append_val(g->children, gc);
-}
-
-int uiGridPadded(uiGrid *g)
-{
- return g->padded;
-}
-
-void uiGridSetPadded(uiGrid *g, int padded)
-{
- g->padded = padded;
- if (g->padded) {
- gtk_grid_set_row_spacing(g->grid, gtkYPadding);
- gtk_grid_set_column_spacing(g->grid, gtkXPadding);
- } else {
- gtk_grid_set_row_spacing(g->grid, 0);
- gtk_grid_set_column_spacing(g->grid, 0);
- }
-}
-
-uiGrid *uiNewGrid(void)
-{
- uiGrid *g;
-
- uiUnixNewControl(uiGrid, g);
-
- g->widget = gtk_grid_new();
- g->container = GTK_CONTAINER(g->widget);
- g->grid = GTK_GRID(g->widget);
-
- g->children = g_array_new(FALSE, TRUE, sizeof (struct gridChild));
-
- return g;
-}
diff --git a/src/libui_sdl/libui/unix/group.c b/src/libui_sdl/libui/unix/group.c
deleted file mode 100644
index 6238a1b..0000000
--- a/src/libui_sdl/libui/unix/group.c
+++ /dev/null
@@ -1,89 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiGroup {
- uiUnixControl c;
- GtkWidget *widget;
- GtkContainer *container;
- GtkBin *bin;
- GtkFrame *frame;
-
- // unfortunately, even though a GtkFrame is a GtkBin, calling gtk_container_set_border_width() on it /includes/ the GtkFrame's label; we don't want tht
- struct child *child;
-
- int margined;
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiGroup)
-
-static void uiGroupDestroy(uiControl *c)
-{
- uiGroup *g = uiGroup(c);
-
- if (g->child != NULL)
- childDestroy(g->child);
- g_object_unref(g->widget);
- uiFreeControl(uiControl(g));
-}
-
-char *uiGroupTitle(uiGroup *g)
-{
- return uiUnixStrdupText(gtk_frame_get_label(g->frame));
-}
-
-void uiGroupSetTitle(uiGroup *g, const char *text)
-{
- gtk_frame_set_label(g->frame, text);
-}
-
-void uiGroupSetChild(uiGroup *g, uiControl *child)
-{
- if (g->child != NULL)
- childRemove(g->child);
- g->child = newChildWithBox(child, uiControl(g), g->container, g->margined);
-}
-
-int uiGroupMargined(uiGroup *g)
-{
- return g->margined;
-}
-
-void uiGroupSetMargined(uiGroup *g, int margined)
-{
- g->margined = margined;
- if (g->child != NULL)
- childSetMargined(g->child, g->margined);
-}
-
-uiGroup *uiNewGroup(const char *text)
-{
- uiGroup *g;
- gfloat yalign;
- GtkLabel *label;
- PangoAttribute *bold;
- PangoAttrList *boldlist;
-
- uiUnixNewControl(uiGroup, g);
-
- g->widget = gtk_frame_new(text);
- g->container = GTK_CONTAINER(g->widget);
- g->bin = GTK_BIN(g->widget);
- g->frame = GTK_FRAME(g->widget);
-
- // with GTK+, groupboxes by default have frames and slightly x-offset regular text
- // they should have no frame and fully left-justified, bold text
- // preserve default y-alignment
- gtk_frame_get_label_align(g->frame, NULL, &yalign);
- gtk_frame_set_label_align(g->frame, 0, yalign);
- gtk_frame_set_shadow_type(g->frame, GTK_SHADOW_NONE);
- label = GTK_LABEL(gtk_frame_get_label_widget(g->frame));
- // this is the boldness level used by GtkPrintUnixDialog
- // (it technically uses "bold" but see pango's pango-enum-types.c for the name conversion; GType is weird)
- bold = pango_attr_weight_new(PANGO_WEIGHT_BOLD);
- boldlist = pango_attr_list_new();
- pango_attr_list_insert(boldlist, bold);
- gtk_label_set_attributes(label, boldlist);
- pango_attr_list_unref(boldlist); // thanks baedert in irc.gimp.net/#gtk+
-
- return g;
-}
diff --git a/src/libui_sdl/libui/unix/image.c b/src/libui_sdl/libui/unix/image.c
deleted file mode 100644
index a79e550..0000000
--- a/src/libui_sdl/libui/unix/image.c
+++ /dev/null
@@ -1,120 +0,0 @@
-// 27 june 2016
-#include "uipriv_unix.h"
-
-struct uiImage {
- double width;
- double height;
- GPtrArray *images;
-};
-
-static void freeImageRep(gpointer item)
-{
- cairo_surface_t *cs = (cairo_surface_t *) item;
- unsigned char *buf;
-
- buf = cairo_image_surface_get_data(cs);
- cairo_surface_destroy(cs);
- uiFree(buf);
-}
-
-uiImage *uiNewImage(double width, double height)
-{
- uiImage *i;
-
- i = uiNew(uiImage);
- i->width = width;
- i->height = height;
- i->images = g_ptr_array_new_with_free_func(freeImageRep);
- return i;
-}
-
-void uiFreeImage(uiImage *i)
-{
- g_ptr_array_free(i->images, TRUE);
- uiFree(i);
-}
-
-void uiImageAppend(uiImage *i, void *pixels, int pixelWidth, int pixelHeight, int pixelStride)
-{
- cairo_surface_t *cs;
- unsigned char *buf, *p;
- uint8_t *src = (uint8_t *) pixels;
- int cstride;
- int y;
-
- cstride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, pixelWidth);
- buf = (unsigned char *) uiAlloc((cstride * pixelHeight * 4) * sizeof (unsigned char), "unsigned char[]");
- p = buf;
- for (y = 0; y < pixelStride * pixelHeight; y += pixelStride) {
- memmove(p, src + y, cstride);
- p += cstride;
- }
- cs = cairo_image_surface_create_for_data(buf, CAIRO_FORMAT_ARGB32,
- pixelWidth, pixelHeight,
- cstride);
- if (cairo_surface_status(cs) != CAIRO_STATUS_SUCCESS)
- /* TODO */;
- cairo_surface_flush(cs);
- g_ptr_array_add(i->images, cs);
-}
-
-struct matcher {
- cairo_surface_t *best;
- int distX;
- int distY;
- int targetX;
- int targetY;
- gboolean foundLarger;
-};
-
-// TODO is this the right algorithm?
-static void match(gpointer surface, gpointer data)
-{
- cairo_surface_t *cs = (cairo_surface_t *) surface;
- struct matcher *m = (struct matcher *) data;
- int x, y;
- int x2, y2;
-
- x = cairo_image_surface_get_width(cs);
- y = cairo_image_surface_get_height(cs);
- if (m->best == NULL)
- goto writeMatch;
-
- if (x < m->targetX && y < m->targetY)
- if (m->foundLarger)
- // always prefer larger ones
- return;
- if (x >= m->targetX && y >= m->targetY && !m->foundLarger)
- // we set foundLarger below
- goto writeMatch;
-
- x2 = abs(m->targetX - x);
- y2 = abs(m->targetY - y);
- if (x2 < m->distX && y2 < m->distY)
- goto writeMatch;
-
- // TODO weight one dimension? threshhold?
- return;
-
-writeMatch:
- // must set this here too; otherwise the first image will never have ths set
- if (x >= m->targetX && y >= m->targetY && !m->foundLarger)
- m->foundLarger = TRUE;
- m->best = cs;
- m->distX = abs(m->targetX - x);
- m->distY = abs(m->targetY - y);
-}
-
-cairo_surface_t *imageAppropriateSurface(uiImage *i, GtkWidget *w)
-{
- struct matcher m;
-
- m.best = NULL;
- m.distX = G_MAXINT;
- m.distY = G_MAXINT;
- m.targetX = i->width * gtk_widget_get_scale_factor(w);
- m.targetY = i->height * gtk_widget_get_scale_factor(w);
- m.foundLarger = FALSE;
- g_ptr_array_foreach(i->images, match, &m);
- return m.best;
-}
diff --git a/src/libui_sdl/libui/unix/label.c b/src/libui_sdl/libui/unix/label.c
deleted file mode 100644
index b39fc7c..0000000
--- a/src/libui_sdl/libui/unix/label.c
+++ /dev/null
@@ -1,36 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiLabel {
- uiUnixControl c;
- GtkWidget *widget;
- GtkMisc *misc;
- GtkLabel *label;
-};
-
-uiUnixControlAllDefaults(uiLabel)
-
-char *uiLabelText(uiLabel *l)
-{
- return uiUnixStrdupText(gtk_label_get_text(l->label));
-}
-
-void uiLabelSetText(uiLabel *l, const char *text)
-{
- gtk_label_set_text(l->label, text);
-}
-
-uiLabel *uiNewLabel(const char *text)
-{
- uiLabel *l;
-
- uiUnixNewControl(uiLabel, l);
-
- l->widget = gtk_label_new(text);
- l->misc = GTK_MISC(l->widget);
- l->label = GTK_LABEL(l->widget);
-
- gtk_misc_set_alignment(l->misc, 0, 0);
-
- return l;
-}
diff --git a/src/libui_sdl/libui/unix/main.c b/src/libui_sdl/libui/unix/main.c
deleted file mode 100644
index 516bd76..0000000
--- a/src/libui_sdl/libui/unix/main.c
+++ /dev/null
@@ -1,147 +0,0 @@
-// 6 april 2015
-#include "uipriv_unix.h"
-
-uiInitOptions options;
-
-// kind of a hack
-GThread* gtkthread;
-GMutex glmutex;
-
-static void _eventfilter(GdkEvent* evt, gpointer data)
-{
- if (evt->type == GDK_EXPOSE)
- {
- g_mutex_lock(&glmutex);
- gtk_main_do_event(evt);
- g_mutex_unlock(&glmutex);
- return;
- }
-
- gtk_main_do_event(evt);
-}
-
-static void _eventfilterdestroy(gpointer data)
-{
- printf("DELET\n");
-}
-
-const char *uiInit(uiInitOptions *o)
-{
- GError *err = NULL;
- const char *msg;
-
- options = *o;
- if (gtk_init_with_args(NULL, NULL, NULL, NULL, NULL, &err) == FALSE) {
- msg = g_strdup(err->message);
- g_error_free(err);
- return msg;
- }
- initAlloc();
- loadFutures();
-
- gtkthread = g_thread_self();
- g_mutex_init(&glmutex);
-
- GList* iconlist = NULL;
- iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_16x16.png", NULL));
- iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_32x32.png", NULL));
- iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_48x48.png", NULL));
- iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_64x64.png", NULL));
- iconlist = g_list_append(iconlist, gdk_pixbuf_new_from_resource("/org/kuriboland/melonDS/icon/melon_128x128.png", NULL));
-
- gtk_window_set_default_icon_list(iconlist);
-
- g_mutex_init(&glmutex);
-
- gdk_event_handler_set(_eventfilter, NULL, _eventfilterdestroy);
-
- return NULL;
-}
-
-void uiUninit(void)
-{
- uninitMenus();
- uninitAlloc();
-}
-
-void uiFreeInitError(const char *err)
-{
- g_free((gpointer) err);
-}
-
-static gboolean (*iteration)(gboolean) = NULL;
-
-void uiMain(void)
-{
- iteration = gtk_main_iteration_do;
- gtk_main();
-}
-
-static gboolean stepsQuit = FALSE;
-
-// the only difference is we ignore the return value from gtk_main_iteration_do(), since it will always be TRUE if gtk_main() was never called
-// gtk_main_iteration_do() will still run the main loop regardless
-static gboolean stepsIteration(gboolean block)
-{
- gtk_main_iteration_do(block);
- return stepsQuit;
-}
-
-void uiMainSteps(void)
-{
- iteration = stepsIteration;
-}
-
-int uiMainStep(int wait)
-{
- gboolean block;
-
- block = FALSE;
- if (wait)
- block = TRUE;
- return (*iteration)(block) == FALSE;
-}
-
-// gtk_main_quit() may run immediately, or it may wait for other pending events; "it depends" (thanks mclasen in irc.gimp.net/#gtk+)
-// PostQuitMessage() on Windows always waits, so we must do so too
-// we'll do it by using an idle callback
-static gboolean quit(gpointer data)
-{
- if (iteration == stepsIteration)
- stepsQuit = TRUE;
- // TODO run a gtk_main() here just to do the cleanup steps of syncing the clipboard and other stuff gtk_main() does before it returns
- else
- gtk_main_quit();
- return FALSE;
-}
-
-void uiQuit(void)
-{
- gdk_threads_add_idle(quit, NULL);
-}
-
-struct queued {
- void (*f)(void *);
- void *data;
-};
-
-static gboolean doqueued(gpointer data)
-{
- struct queued *q = (struct queued *) data;
-
- (*(q->f))(q->data);
- g_free(q);
- return FALSE;
-}
-
-void uiQueueMain(void (*f)(void *data), void *data)
-{
- struct queued *q;
-
- // we have to use g_new0()/g_free() because uiAlloc() is only safe to call on the main thread
- // for some reason it didn't affect me, but it did affect krakjoe
- q = g_new0(struct queued, 1);
- q->f = f;
- q->data = data;
- gdk_threads_add_idle(doqueued, q);
-}
diff --git a/src/libui_sdl/libui/unix/menu.c b/src/libui_sdl/libui/unix/menu.c
deleted file mode 100644
index d641426..0000000
--- a/src/libui_sdl/libui/unix/menu.c
+++ /dev/null
@@ -1,432 +0,0 @@
-// 23 april 2015
-#include "uipriv_unix.h"
-
-static GArray *menus = NULL;
-static guint nmenus = 0;
-static gboolean menusFinalized = FALSE;
-static gboolean hasQuit = FALSE;
-static gboolean hasPreferences = FALSE;
-static gboolean hasAbout = FALSE;
-
-struct uiMenu {
- char *name;
- GArray *items; // []*uiMenuItem
- gboolean ischild;
- guint id;
-};
-
-struct uiMenuItem {
- char *name;
- int type;
- void (*onClicked)(uiMenuItem *, uiWindow *, void *);
- void *onClickedData;
- GType gtype; // template for new instances; kept in sync with everything else
- gboolean disabled;
- gboolean checked;
- GHashTable *windows; // map[GtkMenuItem]*menuItemWindow
- uiMenu *popupchild;
-};
-
-struct menuItemWindow {
- uiWindow *w;
- gulong signal;
-};
-
-enum {
- typeRegular,
- typeCheckbox,
- typeQuit,
- typePreferences,
- typeAbout,
- typeSeparator,
- typeSubmenu,
-};
-
-// we do NOT want programmatic updates to raise an ::activated signal
-static void singleSetChecked(GtkCheckMenuItem *menuitem, gboolean checked, gulong signal)
-{
- g_signal_handler_block(menuitem, signal);
- gtk_check_menu_item_set_active(menuitem, checked);
- g_signal_handler_unblock(menuitem, signal);
-}
-
-static void setChecked(uiMenuItem *item, gboolean checked)
-{
- GHashTableIter iter;
- gpointer widget;
- gpointer ww;
- struct menuItemWindow *w;
-
- item->checked = checked;
- g_hash_table_iter_init(&iter, item->windows);
- while (g_hash_table_iter_next(&iter, &widget, &ww)) {
- w = (struct menuItemWindow *) ww;
- singleSetChecked(GTK_CHECK_MENU_ITEM(widget), item->checked, w->signal);
- }
-}
-
-static void onClicked(GtkMenuItem *menuitem, gpointer data)
-{
- uiMenuItem *item = uiMenuItem(data);
- struct menuItemWindow *w;
-
- // we need to manually update the checked states of all menu items if one changes
- // notice that this is getting the checked state of the menu item that this signal is sent from
- if (item->type == typeCheckbox)
- setChecked(item, gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(menuitem)));
-
- w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, menuitem);
- (*(item->onClicked))(item, w->w, item->onClickedData);
-}
-
-static void defaultOnClicked(uiMenuItem *item, uiWindow *w, void *data)
-{
- // do nothing
-}
-
-static void onQuitClicked(uiMenuItem *item, uiWindow *w, void *data)
-{
- if (shouldQuit())
- uiQuit();
-}
-
-static void menuItemEnableDisable(uiMenuItem *item, gboolean enabled)
-{
- GHashTableIter iter;
- gpointer widget;
-
- item->disabled = !enabled;
- g_hash_table_iter_init(&iter, item->windows);
- while (g_hash_table_iter_next(&iter, &widget, NULL))
- gtk_widget_set_sensitive(GTK_WIDGET(widget), enabled);
-}
-
-void uiMenuItemEnable(uiMenuItem *item)
-{
- menuItemEnableDisable(item, TRUE);
-}
-
-void uiMenuItemDisable(uiMenuItem *item)
-{
- menuItemEnableDisable(item, FALSE);
-}
-
-void uiMenuItemOnClicked(uiMenuItem *item, void (*f)(uiMenuItem *, uiWindow *, void *), void *data)
-{
- if (item->type == typeQuit)
- userbug("You cannot call uiMenuItemOnClicked() on a Quit item; use uiOnShouldQuit() instead.");
- item->onClicked = f;
- item->onClickedData = data;
-}
-
-int uiMenuItemChecked(uiMenuItem *item)
-{
- return item->checked != FALSE;
-}
-
-void uiMenuItemSetChecked(uiMenuItem *item, int checked)
-{
- gboolean c;
-
- // use explicit values
- c = FALSE;
- if (checked)
- c = TRUE;
- setChecked(item, c);
-}
-
-static uiMenuItem *newItem(uiMenu *m, int type, const char *name)
-{
- uiMenuItem *item;
-
- if (menusFinalized)
- userbug("You cannot create a new menu item after menus have been finalized.");
-
- item = uiNew(uiMenuItem);
-
- g_array_append_val(m->items, item);
-
- item->type = type;
- switch (item->type) {
- case typeQuit:
- item->name = g_strdup("Quit");
- break;
- case typePreferences:
- item->name = g_strdup("Preferences...");
- break;
- case typeAbout:
- item->name = g_strdup("About");
- break;
- case typeSeparator:
- break;
- default:
- item->name = g_strdup(name);
- break;
- }
-
- if (item->type == typeQuit) {
- // can't call uiMenuItemOnClicked() here
- item->onClicked = onQuitClicked;
- item->onClickedData = NULL;
- } else
- uiMenuItemOnClicked(item, defaultOnClicked, NULL);
-
- switch (item->type) {
- case typeCheckbox:
- item->gtype = GTK_TYPE_CHECK_MENU_ITEM;
- break;
- case typeSeparator:
- item->gtype = GTK_TYPE_SEPARATOR_MENU_ITEM;
- break;
- default:
- item->gtype = GTK_TYPE_MENU_ITEM;
- break;
- }
-
- item->windows = g_hash_table_new(g_direct_hash, g_direct_equal);
- item->popupchild = NULL;
-
- return item;
-}
-
-uiMenuItem *uiMenuAppendSubmenu(uiMenu *m, uiMenu* child)
-{
- uiMenuItem *item;
-
- if (menusFinalized)
- userbug("You cannot create a new menu item after menus have been finalized.");
-
- item = uiNew(uiMenuItem);
-
- g_array_append_val(m->items, item);
-
- item->type = typeSubmenu;
- item->name = child->name;
-
- uiMenuItemOnClicked(item, defaultOnClicked, NULL);
-
- // checkme
- item->gtype = GTK_TYPE_MENU_ITEM;
-
- item->windows = g_hash_table_new(g_direct_hash, g_direct_equal);
- item->popupchild = child;
- child->ischild = TRUE;
-
- return item;
-}
-
-uiMenuItem *uiMenuAppendItem(uiMenu *m, const char *name)
-{
- return newItem(m, typeRegular, name);
-}
-
-uiMenuItem *uiMenuAppendCheckItem(uiMenu *m, const char *name)
-{
- return newItem(m, typeCheckbox, name);
-}
-
-uiMenuItem *uiMenuAppendQuitItem(uiMenu *m)
-{
- if (hasQuit)
- userbug("You cannot have multiple Quit menu items in the same program.");
- hasQuit = TRUE;
- newItem(m, typeSeparator, NULL);
- return newItem(m, typeQuit, NULL);
-}
-
-uiMenuItem *uiMenuAppendPreferencesItem(uiMenu *m)
-{
- if (hasPreferences)
- userbug("You cannot have multiple Preferences menu items in the same program.");
- hasPreferences = TRUE;
- newItem(m, typeSeparator, NULL);
- return newItem(m, typePreferences, NULL);
-}
-
-uiMenuItem *uiMenuAppendAboutItem(uiMenu *m)
-{
- if (hasAbout)
- userbug("You cannot have multiple About menu items in the same program.");
- hasAbout = TRUE;
- newItem(m, typeSeparator, NULL);
- return newItem(m, typeAbout, NULL);
-}
-
-void uiMenuAppendSeparator(uiMenu *m)
-{
- newItem(m, typeSeparator, NULL);
-}
-
-uiMenu *uiNewMenu(const char *name)
-{
- uiMenu *m;
-
- if (menusFinalized)
- userbug("You cannot create a new menu after menus have been finalized.");
- if (menus == NULL)
- menus = g_array_new(FALSE, TRUE, sizeof (uiMenu *));
-
- m = uiNew(uiMenu);
-
- g_array_append_val(menus, m);
- m->id = nmenus;
- nmenus++;
-
- m->name = g_strdup(name);
- m->items = g_array_new(FALSE, TRUE, sizeof (uiMenuItem *));
- m->ischild = FALSE;
-
- return m;
-}
-
-static void appendMenuItem(GtkMenuShell *submenu, uiMenuItem *item, uiWindow *w)
-{
- GtkWidget *menuitem;
- gulong signal;
- struct menuItemWindow *ww;
-
- menuitem = g_object_new(item->gtype, NULL);
- if (item->name != NULL)
- gtk_menu_item_set_label(GTK_MENU_ITEM(menuitem), item->name);
- if (item->type != typeSeparator) {
- signal = g_signal_connect(menuitem, "activate", G_CALLBACK(onClicked), item);
- gtk_widget_set_sensitive(menuitem, !item->disabled);
- if (item->type == typeCheckbox)
- singleSetChecked(GTK_CHECK_MENU_ITEM(menuitem), item->checked, signal);
- }
- gtk_menu_shell_append(submenu, menuitem);
-
- ww = uiNew(struct menuItemWindow);
- ww->w = w;
- ww->signal = signal;
- g_hash_table_insert(item->windows, menuitem, ww);
-
- if (item->popupchild != NULL)
- {
- int j;
- uiMenu* m;
- GtkWidget *c_submenu;
-
- m = item->popupchild;
- c_submenu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), c_submenu);
- for (j = 0; j < m->items->len; j++)
- appendMenuItem(GTK_MENU_SHELL(c_submenu), g_array_index(m->items, uiMenuItem *, j), w);
- }
-}
-
-GtkWidget *makeMenubar(uiWindow *w)
-{
- GtkWidget *menubar;
- guint i, j;
- uiMenu *m;
- GtkWidget *menuitem;
- GtkWidget *submenu;
-
- menusFinalized = TRUE;
-
- menubar = gtk_menu_bar_new();
-
- if (menus != NULL)
- for (i = 0; i < menus->len; i++) {
- m = g_array_index(menus, uiMenu *, i);
- if (m->ischild) continue;
- menuitem = gtk_menu_item_new_with_label(m->name);
- submenu = gtk_menu_new();
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
- for (j = 0; j < m->items->len; j++)
- appendMenuItem(GTK_MENU_SHELL(submenu), g_array_index(m->items, uiMenuItem *, j), w);
- gtk_menu_shell_append(GTK_MENU_SHELL(menubar), menuitem);
- }
-
- gtk_widget_set_hexpand(menubar, TRUE);
- gtk_widget_set_halign(menubar, GTK_ALIGN_FILL);
- return menubar;
-}
-
-struct freeMenuItemData {
- GArray *items;
- guint i;
- guint* parent_i;
-};
-
-static void freeMenu(GtkWidget *widget, gpointer data);
-
-static void freeMenuItem(GtkWidget *widget, gpointer data)
-{
- struct freeMenuItemData *fmi = (struct freeMenuItemData *) data;
- uiMenuItem *item;
- struct menuItemWindow *w;
-
- item = g_array_index(fmi->items, uiMenuItem *, fmi->i);
- if (item->popupchild != NULL)
- freeMenu(widget, fmi->parent_i);//&item->popupchild->id);
- w = (struct menuItemWindow *) g_hash_table_lookup(item->windows, widget);
- if (g_hash_table_remove(item->windows, widget) == FALSE)
- implbug("GtkMenuItem %p not in menu item's item/window map", widget);
- uiFree(w);
- fmi->i++;
-}
-
-static void freeMenu(GtkWidget *widget, gpointer data)
-{
- guint *i = (guint *) data;
- uiMenu *m;
- GtkMenuItem *item;
- GtkWidget *submenu;
- struct freeMenuItemData fmi;
-
- m = g_array_index(menus, uiMenu *, *i);
- item = GTK_MENU_ITEM(widget);
- submenu = gtk_menu_item_get_submenu(item);
- fmi.items = m->items;
- fmi.i = 0;
- (*i)++;
- fmi.parent_i = i;
- gtk_container_foreach(GTK_CONTAINER(submenu), freeMenuItem, &fmi);
- //(*i)++;
-}
-
-void freeMenubar(GtkWidget *mb)
-{
- guint i;
-
- i = 0;
- gtk_container_foreach(GTK_CONTAINER(mb), freeMenu, &i);
- // no need to worry about destroying any widgets; destruction of the window they're in will do it for us
-}
-
-void _freeMenu(uiMenu* m)
-{
- uiMenuItem *item;
- guint j;
-
- g_free(m->name);
- for (j = 0; j < m->items->len; j++) {
- item = g_array_index(m->items, uiMenuItem *, j);
- if (item->popupchild != NULL) _freeMenu(item->popupchild);
- if (g_hash_table_size(item->windows) != 0)
- // TODO is this really a userbug()?
- implbug("menu item %p (%s) still has uiWindows attached; did you forget to destroy some windows?", item, item->name);
- if (item->type != typeSubmenu) g_free(item->name);
- g_hash_table_destroy(item->windows);
- uiFree(item);
- }
- g_array_free(m->items, TRUE);
- uiFree(m);
-}
-
-void uninitMenus(void)
-{
- uiMenu *m;
- guint i;
-
- if (menus == NULL)
- return;
- for (i = 0; i < menus->len; i++) {
- m = g_array_index(menus, uiMenu *, i);
- if (m->ischild) continue;
- _freeMenu(m);
- }
- g_array_free(menus, TRUE);
-}
diff --git a/src/libui_sdl/libui/unix/multilineentry.c b/src/libui_sdl/libui/unix/multilineentry.c
deleted file mode 100644
index 09ffd46..0000000
--- a/src/libui_sdl/libui/unix/multilineentry.c
+++ /dev/null
@@ -1,124 +0,0 @@
-// 6 december 2015
-#include "uipriv_unix.h"
-
-struct uiMultilineEntry {
- uiUnixControl c;
- GtkWidget *widget;
- GtkContainer *scontainer;
- GtkScrolledWindow *sw;
- GtkWidget *textviewWidget;
- GtkTextView *textview;
- GtkTextBuffer *textbuf;
- void (*onChanged)(uiMultilineEntry *, void *);
- void *onChangedData;
- gulong onChangedSignal;
-};
-
-uiUnixControlAllDefaults(uiMultilineEntry)
-
-static void onChanged(GtkTextBuffer *textbuf, gpointer data)
-{
- uiMultilineEntry *e = uiMultilineEntry(data);
-
- (*(e->onChanged))(e, e->onChangedData);
-}
-
-static void defaultOnChanged(uiMultilineEntry *e, void *data)
-{
- // do nothing
-}
-
-char *uiMultilineEntryText(uiMultilineEntry *e)
-{
- GtkTextIter start, end;
- char *tret, *out;
-
- gtk_text_buffer_get_start_iter(e->textbuf, &start);
- gtk_text_buffer_get_end_iter(e->textbuf, &end);
- tret = gtk_text_buffer_get_text(e->textbuf, &start, &end, TRUE);
- // theoretically we could just return tret because uiUnixStrdupText() is just g_strdup(), but if that ever changes we can't, so let's do it this way to be safe
- out = uiUnixStrdupText(tret);
- g_free(tret);
- return out;
-}
-
-void uiMultilineEntrySetText(uiMultilineEntry *e, const char *text)
-{
- // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
- g_signal_handler_block(e->textbuf, e->onChangedSignal);
- gtk_text_buffer_set_text(e->textbuf, text, -1);
- g_signal_handler_unblock(e->textbuf, e->onChangedSignal);
-}
-
-// TODO scroll to end?
-void uiMultilineEntryAppend(uiMultilineEntry *e, const char *text)
-{
- GtkTextIter end;
-
- gtk_text_buffer_get_end_iter(e->textbuf, &end);
- // we need to inhibit sending of ::changed because this WILL send a ::changed otherwise
- g_signal_handler_block(e->textbuf, e->onChangedSignal);
- gtk_text_buffer_insert(e->textbuf, &end, text, -1);
- g_signal_handler_unblock(e->textbuf, e->onChangedSignal);
-}
-
-void uiMultilineEntryOnChanged(uiMultilineEntry *e, void (*f)(uiMultilineEntry *e, void *data), void *data)
-{
- e->onChanged = f;
- e->onChangedData = data;
-}
-
-int uiMultilineEntryReadOnly(uiMultilineEntry *e)
-{
- return gtk_text_view_get_editable(e->textview) == FALSE;
-}
-
-void uiMultilineEntrySetReadOnly(uiMultilineEntry *e, int readonly)
-{
- gboolean editable;
-
- editable = TRUE;
- if (readonly)
- editable = FALSE;
- gtk_text_view_set_editable(e->textview, editable);
-}
-
-static uiMultilineEntry *finishMultilineEntry(GtkPolicyType hpolicy, GtkWrapMode wrapMode)
-{
- uiMultilineEntry *e;
-
- uiUnixNewControl(uiMultilineEntry, e);
-
- e->widget = gtk_scrolled_window_new(NULL, NULL);
- e->scontainer = GTK_CONTAINER(e->widget);
- e->sw = GTK_SCROLLED_WINDOW(e->widget);
- gtk_scrolled_window_set_policy(e->sw,
- hpolicy,
- GTK_POLICY_AUTOMATIC);
- gtk_scrolled_window_set_shadow_type(e->sw, GTK_SHADOW_IN);
-
- e->textviewWidget = gtk_text_view_new();
- e->textview = GTK_TEXT_VIEW(e->textviewWidget);
- gtk_text_view_set_wrap_mode(e->textview, wrapMode);
-
- gtk_container_add(e->scontainer, e->textviewWidget);
- // and make the text view visible; only the scrolled window's visibility is controlled by libui
- gtk_widget_show(e->textviewWidget);
-
- e->textbuf = gtk_text_view_get_buffer(e->textview);
-
- e->onChangedSignal = g_signal_connect(e->textbuf, "changed", G_CALLBACK(onChanged), e);
- uiMultilineEntryOnChanged(e, defaultOnChanged, NULL);
-
- return e;
-}
-
-uiMultilineEntry *uiNewMultilineEntry(void)
-{
- return finishMultilineEntry(GTK_POLICY_NEVER, GTK_WRAP_WORD);
-}
-
-uiMultilineEntry *uiNewNonWrappingMultilineEntry(void)
-{
- return finishMultilineEntry(GTK_POLICY_AUTOMATIC, GTK_WRAP_NONE);
-}
diff --git a/src/libui_sdl/libui/unix/progressbar.c b/src/libui_sdl/libui/unix/progressbar.c
deleted file mode 100644
index 9b543b0..0000000
--- a/src/libui_sdl/libui/unix/progressbar.c
+++ /dev/null
@@ -1,71 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiProgressBar {
- uiUnixControl c;
- GtkWidget *widget;
- GtkProgressBar *pbar;
- gboolean indeterminate;
- guint pulser;
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiProgressBar)
-
-static void uiProgressBarDestroy(uiControl *c)
-{
- uiProgressBar *p = uiProgressBar(c);
-
- // be sure to stop the timeout now
- if (p->indeterminate)
- g_source_remove(p->pulser);
- g_object_unref(p->widget);
- uiFreeControl(uiControl(p));
-}
-
-int uiProgressBarValue(uiProgressBar *p)
-{
- if (p->indeterminate)
- return -1;
- return (int) (gtk_progress_bar_get_fraction(p->pbar) * 100);
-}
-
-static gboolean pulse(void* data)
-{
- uiProgressBar *p = uiProgressBar(data);
-
- gtk_progress_bar_pulse(p->pbar);
- return TRUE;
-}
-
-void uiProgressBarSetValue(uiProgressBar *p, int value)
-{
- if (value == -1) {
- if (!p->indeterminate) {
- p->indeterminate = TRUE;
- // TODO verify the timeout
- p->pulser = g_timeout_add(100, pulse, p);
- }
- return;
- }
- if (p->indeterminate) {
- p->indeterminate = FALSE;
- g_source_remove(p->pulser);
- }
-
- if (value < 0 || value > 100)
- userbug("Value %d is out of range for a uiProgressBar.", value);
-
- gtk_progress_bar_set_fraction(p->pbar, ((gdouble) value) / 100);
-}
-
-uiProgressBar *uiNewProgressBar(void)
-{
- uiProgressBar *p;
-
- uiUnixNewControl(uiProgressBar, p);
-
- p->widget = gtk_progress_bar_new();
- p->pbar = GTK_PROGRESS_BAR(p->widget);
-
- return p;
-}
diff --git a/src/libui_sdl/libui/unix/radiobuttons.c b/src/libui_sdl/libui/unix/radiobuttons.c
deleted file mode 100644
index da41107..0000000
--- a/src/libui_sdl/libui/unix/radiobuttons.c
+++ /dev/null
@@ -1,121 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-// on GTK+ a uiRadioButtons is a GtkBox with each of the GtkRadioButtons as children
-
-struct uiRadioButtons {
- uiUnixControl c;
- GtkWidget *widget;
- GtkContainer *container;
- GtkBox *box;
- GPtrArray *buttons;
- void (*onSelected)(uiRadioButtons *, void *);
- void *onSelectedData;
- gboolean changing;
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiRadioButtons)
-
-static void defaultOnSelected(uiRadioButtons *r, void *data)
-{
- // do nothing
-}
-
-static void onToggled(GtkToggleButton *tb, gpointer data)
-{
- uiRadioButtons *r = uiRadioButtons(data);
-
- // only care if a button is selected
- if (!gtk_toggle_button_get_active(tb))
- return;
- // ignore programmatic changes
- if (r->changing)
- return;
- (*(r->onSelected))(r, r->onSelectedData);
-}
-
-static void uiRadioButtonsDestroy(uiControl *c)
-{
- uiRadioButtons *r = uiRadioButtons(c);
- GtkWidget *b;
-
- while (r->buttons->len != 0) {
- b = GTK_WIDGET(g_ptr_array_remove_index(r->buttons, 0));
- gtk_widget_destroy(b);
- }
- g_ptr_array_free(r->buttons, TRUE);
- // and free ourselves
- g_object_unref(r->widget);
- uiFreeControl(uiControl(r));
-}
-
-void uiRadioButtonsAppend(uiRadioButtons *r, const char *text)
-{
- GtkWidget *rb;
- GtkRadioButton *previous;
-
- previous = NULL;
- if (r->buttons->len > 0)
- previous = GTK_RADIO_BUTTON(g_ptr_array_index(r->buttons, 0));
- rb = gtk_radio_button_new_with_label_from_widget(previous, text);
- g_signal_connect(rb, "toggled", G_CALLBACK(onToggled), r);
- gtk_container_add(r->container, rb);
- g_ptr_array_add(r->buttons, rb);
- gtk_widget_show(rb);
-}
-
-int uiRadioButtonsSelected(uiRadioButtons *r)
-{
- GtkToggleButton *tb;
- guint i;
-
- for (i = 0; i < r->buttons->len; i++) {
- tb = GTK_TOGGLE_BUTTON(g_ptr_array_index(r->buttons, i));
- if (gtk_toggle_button_get_active(tb))
- return i;
- }
- return -1;
-}
-
-void uiRadioButtonsSetSelected(uiRadioButtons *r, int n)
-{
- GtkToggleButton *tb;
- gboolean active;
-
- active = TRUE;
- // TODO this doesn't work
- if (n == -1) {
- n = uiRadioButtonsSelected(r);
- if (n == -1) // no selection; keep it that way
- return;
- active = FALSE;
- }
- tb = GTK_TOGGLE_BUTTON(g_ptr_array_index(r->buttons, n));
- // this is easier than remembering all the signals
- r->changing = TRUE;
- gtk_toggle_button_set_active(tb, active);
- r->changing = FALSE;
-}
-
-void uiRadioButtonsOnSelected(uiRadioButtons *r, void (*f)(uiRadioButtons *, void *), void *data)
-{
- r->onSelected = f;
- r->onSelectedData = data;
-}
-
-uiRadioButtons *uiNewRadioButtons(void)
-{
- uiRadioButtons *r;
-
- uiUnixNewControl(uiRadioButtons, r);
-
- r->widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- r->container = GTK_CONTAINER(r->widget);
- r->box = GTK_BOX(r->widget);
-
- r->buttons = g_ptr_array_new();
-
- uiRadioButtonsOnSelected(r, defaultOnSelected, NULL);
-
- return r;
-}
diff --git a/src/libui_sdl/libui/unix/separator.c b/src/libui_sdl/libui/unix/separator.c
deleted file mode 100644
index 02c75da..0000000
--- a/src/libui_sdl/libui/unix/separator.c
+++ /dev/null
@@ -1,34 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiSeparator {
- uiUnixControl c;
- GtkWidget *widget;
- GtkSeparator *separator;
-};
-
-uiUnixControlAllDefaults(uiSeparator)
-
-uiSeparator *uiNewHorizontalSeparator(void)
-{
- uiSeparator *s;
-
- uiUnixNewControl(uiSeparator, s);
-
- s->widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
- s->separator = GTK_SEPARATOR(s->widget);
-
- return s;
-}
-
-uiSeparator *uiNewVerticalSeparator(void)
-{
- uiSeparator *s;
-
- uiUnixNewControl(uiSeparator, s);
-
- s->widget = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
- s->separator = GTK_SEPARATOR(s->widget);
-
- return s;
-}
diff --git a/src/libui_sdl/libui/unix/slider.c b/src/libui_sdl/libui/unix/slider.c
deleted file mode 100644
index 7f0cc24..0000000
--- a/src/libui_sdl/libui/unix/slider.c
+++ /dev/null
@@ -1,71 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiSlider {
- uiUnixControl c;
- GtkWidget *widget;
- GtkRange *range;
- GtkScale *scale;
- void (*onChanged)(uiSlider *, void *);
- void *onChangedData;
- gulong onChangedSignal;
-};
-
-uiUnixControlAllDefaults(uiSlider)
-
-static void onChanged(GtkRange *range, gpointer data)
-{
- uiSlider *s = uiSlider(data);
-
- (*(s->onChanged))(s, s->onChangedData);
-}
-
-static void defaultOnChanged(uiSlider *s, void *data)
-{
- // do nothing
-}
-
-int uiSliderValue(uiSlider *s)
-{
- return gtk_range_get_value(s->range);
-}
-
-void uiSliderSetValue(uiSlider *s, int value)
-{
- // we need to inhibit sending of ::value-changed because this WILL send a ::value-changed otherwise
- g_signal_handler_block(s->range, s->onChangedSignal);
- gtk_range_set_value(s->range, value);
- g_signal_handler_unblock(s->range, s->onChangedSignal);
-}
-
-void uiSliderOnChanged(uiSlider *s, void (*f)(uiSlider *, void *), void *data)
-{
- s->onChanged = f;
- s->onChangedData = data;
-}
-
-uiSlider *uiNewSlider(int min, int max)
-{
- uiSlider *s;
- int temp;
-
- if (min >= max) {
- temp = min;
- min = max;
- max = temp;
- }
-
- uiUnixNewControl(uiSlider, s);
-
- s->widget = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, min, max, 1);
- s->range = GTK_RANGE(s->widget);
- s->scale = GTK_SCALE(s->widget);
-
- // ensure integers, just to be safe
- gtk_scale_set_digits(s->scale, 0);
-
- s->onChangedSignal = g_signal_connect(s->scale, "value-changed", G_CALLBACK(onChanged), s);
- uiSliderOnChanged(s, defaultOnChanged, NULL);
-
- return s;
-}
diff --git a/src/libui_sdl/libui/unix/spinbox.c b/src/libui_sdl/libui/unix/spinbox.c
deleted file mode 100644
index 90a5d3c..0000000
--- a/src/libui_sdl/libui/unix/spinbox.c
+++ /dev/null
@@ -1,72 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiSpinbox {
- uiUnixControl c;
- GtkWidget *widget;
- GtkEntry *entry;
- GtkSpinButton *spinButton;
- void (*onChanged)(uiSpinbox *, void *);
- void *onChangedData;
- gulong onChangedSignal;
-};
-
-uiUnixControlAllDefaults(uiSpinbox)
-
-static void onChanged(GtkSpinButton *sb, gpointer data)
-{
- uiSpinbox *s = uiSpinbox(data);
-
- (*(s->onChanged))(s, s->onChangedData);
-}
-
-static void defaultOnChanged(uiSpinbox *s, void *data)
-{
- // do nothing
-}
-
-int uiSpinboxValue(uiSpinbox *s)
-{
- return gtk_spin_button_get_value(s->spinButton);
-}
-
-void uiSpinboxSetValue(uiSpinbox *s, int value)
-{
- // we need to inhibit sending of ::value-changed because this WILL send a ::value-changed otherwise
- g_signal_handler_block(s->spinButton, s->onChangedSignal);
- // this clamps for us
- gtk_spin_button_set_value(s->spinButton, (gdouble) value);
- g_signal_handler_unblock(s->spinButton, s->onChangedSignal);
-}
-
-void uiSpinboxOnChanged(uiSpinbox *s, void (*f)(uiSpinbox *, void *), void *data)
-{
- s->onChanged = f;
- s->onChangedData = data;
-}
-
-uiSpinbox *uiNewSpinbox(int min, int max)
-{
- uiSpinbox *s;
- int temp;
-
- if (min >= max) {
- temp = min;
- min = max;
- max = temp;
- }
-
- uiUnixNewControl(uiSpinbox, s);
-
- s->widget = gtk_spin_button_new_with_range(min, max, 1);
- s->entry = GTK_ENTRY(s->widget);
- s->spinButton = GTK_SPIN_BUTTON(s->widget);
-
- // ensure integers, just to be safe
- gtk_spin_button_set_digits(s->spinButton, 0);
-
- s->onChangedSignal = g_signal_connect(s->spinButton, "value-changed", G_CALLBACK(onChanged), s);
- uiSpinboxOnChanged(s, defaultOnChanged, NULL);
-
- return s;
-}
diff --git a/src/libui_sdl/libui/unix/stddialogs.c b/src/libui_sdl/libui/unix/stddialogs.c
deleted file mode 100644
index 3daeffa..0000000
--- a/src/libui_sdl/libui/unix/stddialogs.c
+++ /dev/null
@@ -1,116 +0,0 @@
-// 26 june 2015
-#include "uipriv_unix.h"
-
-// LONGTERM figure out why, and describe, that this is the desired behavior
-// LONGTERM also point out that font and color buttons also work like this
-
-#define windowWindow(w) ((w)?(GTK_WINDOW(uiControlHandle(uiControl(w)))):NULL)
-
-static char *filedialog(GtkWindow *parent, GtkFileChooserAction mode, const gchar *confirm, const char* filter, const char* initpath)
-{
- GtkWidget *fcd;
- GtkFileChooser *fc;
- gint response;
- char *filename;
-
- fcd = gtk_file_chooser_dialog_new(NULL, parent, mode,
- "_Cancel", GTK_RESPONSE_CANCEL,
- confirm, GTK_RESPONSE_ACCEPT,
- NULL);
- fc = GTK_FILE_CHOOSER(fcd);
-
- // filters
- {
- gchar _filter[256];
- gchar* fp = &_filter[0]; int s = 0;
- gchar* fname;
- for (int i = 0; i < 255; i++)
- {
- if (filter[i] == '|' || filter[i] == '\0')
- {
- _filter[i] = '\0';
- if (s & 1)
- {
- GtkFileFilter* filter = gtk_file_filter_new();
- gtk_file_filter_set_name(filter, fname);
-
- for (gchar* j = fp; ; j++)
- {
- if (*j == ';')
- {
- *j = '\0';
- gtk_file_filter_add_pattern(filter, fp);
- fp = j+1;
- }
- else if (*j == '\0')
- {
- gtk_file_filter_add_pattern(filter, fp);
- break;
- }
- }
-
- gtk_file_chooser_add_filter(fc, filter);
- }
- else
- {
- fname = fp;
- }
- fp = &_filter[i+1];
- s++;
- if (s >= 8) break;
- if (filter[i] == '\0') break;
- }
- else
- _filter[i] = filter[i];
- }
- }
-
- gtk_file_chooser_set_local_only(fc, FALSE);
- gtk_file_chooser_set_select_multiple(fc, FALSE);
- gtk_file_chooser_set_show_hidden(fc, TRUE);
- gtk_file_chooser_set_do_overwrite_confirmation(fc, TRUE);
- gtk_file_chooser_set_create_folders(fc, TRUE);
- if (initpath && strlen(initpath)>0)
- gtk_file_chooser_set_current_folder(fc, initpath);
-
- response = gtk_dialog_run(GTK_DIALOG(fcd));
- if (response != GTK_RESPONSE_ACCEPT) {
- gtk_widget_destroy(fcd);
- return NULL;
- }
- filename = uiUnixStrdupText(gtk_file_chooser_get_filename(fc));
- gtk_widget_destroy(fcd);
- return filename;
-}
-
-char *uiOpenFile(uiWindow *parent, const char* filter, const char* initpath)
-{
- return filedialog(windowWindow(parent), GTK_FILE_CHOOSER_ACTION_OPEN, "_Open", filter, initpath);
-}
-
-char *uiSaveFile(uiWindow *parent, const char* filter, const char* initpath)
-{
- return filedialog(windowWindow(parent), GTK_FILE_CHOOSER_ACTION_SAVE, "_Save", filter, initpath);
-}
-
-static void msgbox(GtkWindow *parent, const char *title, const char *description, GtkMessageType type, GtkButtonsType buttons)
-{
- GtkWidget *md;
-
- md = gtk_message_dialog_new(parent, GTK_DIALOG_MODAL,
- type, buttons,
- "%s", title);
- gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(md), "%s", description);
- gtk_dialog_run(GTK_DIALOG(md));
- gtk_widget_destroy(md);
-}
-
-void uiMsgBox(uiWindow *parent, const char *title, const char *description)
-{
- msgbox(windowWindow(parent), title, description, GTK_MESSAGE_OTHER, GTK_BUTTONS_OK);
-}
-
-void uiMsgBoxError(uiWindow *parent, const char *title, const char *description)
-{
- msgbox(windowWindow(parent), title, description, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK);
-}
diff --git a/src/libui_sdl/libui/unix/tab.c b/src/libui_sdl/libui/unix/tab.c
deleted file mode 100644
index 552e0e3..0000000
--- a/src/libui_sdl/libui/unix/tab.c
+++ /dev/null
@@ -1,97 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiTab {
- uiUnixControl c;
-
- GtkWidget *widget;
- GtkContainer *container;
- GtkNotebook *notebook;
-
- GArray *pages; // []*struct child
-};
-
-uiUnixControlAllDefaultsExceptDestroy(uiTab)
-
-static void uiTabDestroy(uiControl *c)
-{
- uiTab *t = uiTab(c);
- guint i;
- struct child *page;
-
- for (i = 0; i < t->pages->len; i++) {
- page = g_array_index(t->pages, struct child *, i);
- childDestroy(page);
- }
- g_array_free(t->pages, TRUE);
- // and free ourselves
- g_object_unref(t->widget);
- uiFreeControl(uiControl(t));
-}
-
-void uiTabAppend(uiTab *t, const char *name, uiControl *child)
-{
- uiTabInsertAt(t, name, t->pages->len, child);
-}
-
-void uiTabInsertAt(uiTab *t, const char *name, int n, uiControl *child)
-{
- struct child *page;
-
- // this will create a tab, because of gtk_container_add()
- page = newChildWithBox(child, uiControl(t), t->container, 0);
-
- gtk_notebook_set_tab_label_text(t->notebook, childBox(page), name);
- gtk_notebook_reorder_child(t->notebook, childBox(page), n);
-
- g_array_insert_val(t->pages, n, page);
-}
-
-void uiTabDelete(uiTab *t, int n)
-{
- struct child *page;
-
- page = g_array_index(t->pages, struct child *, n);
- // this will remove the tab, because gtk_widget_destroy() calls gtk_container_remove()
- childRemove(page);
- g_array_remove_index(t->pages, n);
-}
-
-int uiTabNumPages(uiTab *t)
-{
- return t->pages->len;
-}
-
-int uiTabMargined(uiTab *t, int n)
-{
- struct child *page;
-
- page = g_array_index(t->pages, struct child *, n);
- return childFlag(page);
-}
-
-void uiTabSetMargined(uiTab *t, int n, int margined)
-{
- struct child *page;
-
- page = g_array_index(t->pages, struct child *, n);
- childSetFlag(page, margined);
- childSetMargined(page, childFlag(page));
-}
-
-uiTab *uiNewTab(void)
-{
- uiTab *t;
-
- uiUnixNewControl(uiTab, t);
-
- t->widget = gtk_notebook_new();
- t->container = GTK_CONTAINER(t->widget);
- t->notebook = GTK_NOTEBOOK(t->widget);
-
- gtk_notebook_set_scrollable(t->notebook, TRUE);
-
- t->pages = g_array_new(FALSE, TRUE, sizeof (struct child *));
-
- return t;
-}
diff --git a/src/libui_sdl/libui/unix/text.c b/src/libui_sdl/libui/unix/text.c
deleted file mode 100644
index ad92738..0000000
--- a/src/libui_sdl/libui/unix/text.c
+++ /dev/null
@@ -1,12 +0,0 @@
-// 9 april 2015
-#include "uipriv_unix.h"
-
-char *uiUnixStrdupText(const char *t)
-{
- return g_strdup(t);
-}
-
-void uiFreeText(char *t)
-{
- g_free(t);
-}
diff --git a/src/libui_sdl/libui/unix/uipriv_unix.h b/src/libui_sdl/libui/unix/uipriv_unix.h
deleted file mode 100644
index 9b77188..0000000
--- a/src/libui_sdl/libui/unix/uipriv_unix.h
+++ /dev/null
@@ -1,71 +0,0 @@
-// 22 april 2015
-#define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_40
-#define GLIB_VERSION_MAX_ALLOWED GLIB_VERSION_2_40
-#define GDK_VERSION_MIN_REQUIRED GDK_VERSION_3_10
-#define GDK_VERSION_MAX_ALLOWED GDK_VERSION_3_10
-#include <gtk/gtk.h>
-#include <math.h>
-#include <dlfcn.h> // see drawtext.c, gl.c
-#include <langinfo.h>
-#include <string.h>
-#include <stdlib.h>
-#include "../ui.h"
-#include "../ui_unix.h"
-#include "../common/uipriv.h"
-
-#define gtkXMargin 12
-#define gtkYMargin 12
-#define gtkXPadding 12
-#define gtkYPadding 6
-
-// menu.c
-extern GtkWidget *makeMenubar(uiWindow *);
-extern void freeMenubar(GtkWidget *);
-extern void uninitMenus(void);
-
-// alloc.c
-extern void initAlloc(void);
-extern void uninitAlloc(void);
-
-// util.c
-extern void setMargined(GtkContainer *, int);
-
-// child.c
-extern struct child *newChild(uiControl *child, uiControl *parent, GtkContainer *parentContainer);
-extern struct child *newChildWithBox(uiControl *child, uiControl *parent, GtkContainer *parentContainer, int margined);
-extern void childRemove(struct child *c);
-extern void childDestroy(struct child *c);
-extern GtkWidget *childWidget(struct child *c);
-extern int childFlag(struct child *c);
-extern void childSetFlag(struct child *c, int flag);
-extern GtkWidget *childBox(struct child *c);
-extern void childSetMargined(struct child *c, int margined);
-
-// draw.c
-extern uiDrawContext *newContext(cairo_t *);
-extern void freeContext(uiDrawContext *);
-
-// drawtext.c
-extern uiDrawTextFont *mkTextFont(PangoFont *f, gboolean add);
-extern PangoFont *pangoDescToPangoFont(PangoFontDescription *pdesc);
-
-// graphemes.c
-extern ptrdiff_t *graphemes(const char *text, PangoContext *context);
-
-// image.c
-/*TODO remove this*/typedef struct uiImage uiImage;
-extern cairo_surface_t *imageAppropriateSurface(uiImage *i, GtkWidget *w);
-
-// cellrendererbutton.c
-extern GtkCellRenderer *newCellRendererButton(void);
-
-// future.c
-extern void loadFutures(void);
-extern PangoAttribute *FUTURE_pango_attr_foreground_alpha_new(guint16 alpha);
-extern gboolean FUTURE_gtk_widget_path_iter_set_object_name(GtkWidgetPath *path, gint pos, const char *name);
-
-// gl.c
-extern uiGLContext *createGLContext(GtkWidget* widget, int maj, int min);
-extern void freeGLContext(uiGLContext* glctx);
-extern void areaDrawGL(GtkWidget* widget, uiAreaDrawParams* dp, cairo_t* cr, uiGLContext* glctx);
-
diff --git a/src/libui_sdl/libui/unix/util.c b/src/libui_sdl/libui/unix/util.c
deleted file mode 100644
index 7f4f43f..0000000
--- a/src/libui_sdl/libui/unix/util.c
+++ /dev/null
@@ -1,10 +0,0 @@
-// 18 april 2015
-#include "uipriv_unix.h"
-
-void setMargined(GtkContainer *c, int margined)
-{
- if (margined)
- gtk_container_set_border_width(c, gtkXMargin);
- else
- gtk_container_set_border_width(c, 0);
-}
diff --git a/src/libui_sdl/libui/unix/window.c b/src/libui_sdl/libui/unix/window.c
deleted file mode 100644
index 6d5e2de..0000000
--- a/src/libui_sdl/libui/unix/window.c
+++ /dev/null
@@ -1,462 +0,0 @@
-// 11 june 2015
-#include "uipriv_unix.h"
-
-struct uiWindow {
- uiUnixControl c;
-
- GtkWidget *widget;
- GtkContainer *container;
- GtkWindow *window;
-
- GtkWidget *vboxWidget;
- GtkContainer *vboxContainer;
- GtkBox *vbox;
-
- GtkWidget *childHolderWidget;
- GtkContainer *childHolderContainer;
-
- GtkWidget *menubar;
-
- uiControl *child;
- int margined;
-
- int width, height;
-
- int (*onClosing)(uiWindow *, void *);
- void *onClosingData;
- void (*onContentSizeChanged)(uiWindow *, void *);
- void *onContentSizeChangedData;
- void (*onDropFile)(uiWindow *, char *, void *);
- void *onDropFileData;
- void (*onGetFocus)(uiWindow *, void *);
- void *onGetFocusData;
- void (*onLoseFocus)(uiWindow *, void *);
- void *onLoseFocusData;
-
- gboolean fullscreen;
-};
-
-static gboolean onClosing(GtkWidget *win, GdkEvent *e, gpointer data)
-{
- uiWindow *w = uiWindow(data);
-
- // manually destroy the window ourselves; don't let the delete-event handler do it
- if ((*(w->onClosing))(w, w->onClosingData))
- uiControlDestroy(uiControl(w));
- // don't continue to the default delete-event handler; we destroyed the window by now
- return TRUE;
-}
-
-static void onSizeAllocate(GtkWidget *widget, GdkRectangle *allocation, gpointer data)
-{
- uiWindow *w = uiWindow(data);
-
- // TODO deal with spurious size-allocates
- (*(w->onContentSizeChanged))(w, w->onContentSizeChangedData);
-}
-
-static gboolean onGetFocus(GtkWidget *win, GdkEvent *e, gpointer data)
-{
- uiWindow *w = uiWindow(data);
- if (w->onGetFocus)
- w->onGetFocus(w, w->onGetFocusData);
-}
-
-static gboolean onLoseFocus(GtkWidget *win, GdkEvent *e, gpointer data)
-{
- uiWindow *w = uiWindow(data);
- if (w->onLoseFocus)
- w->onLoseFocus(w, w->onLoseFocusData);
-}
-
-static int defaultOnClosing(uiWindow *w, void *data)
-{
- return 0;
-}
-
-static void defaultOnPositionContentSizeChanged(uiWindow *w, void *data)
-{
- // do nothing
-}
-
-static void uiWindowDestroy(uiControl *c)
-{
- uiWindow *w = uiWindow(c);
-
- // first hide ourselves
- gtk_widget_hide(w->widget);
- // now destroy the child
- if (w->child != NULL) {
- uiControlSetParent(w->child, NULL);
- uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, TRUE);
- uiControlDestroy(w->child);
- }
- // now destroy the menus, if any
- if (w->menubar != NULL)
- freeMenubar(w->menubar);
- gtk_widget_destroy(w->childHolderWidget);
- gtk_widget_destroy(w->vboxWidget);
- // and finally free ourselves
- // use gtk_widget_destroy() instead of g_object_unref() because GTK+ has internal references (see #165)
- gtk_widget_destroy(w->widget);
- uiFreeControl(uiControl(w));
-}
-
-void uiWindowSetPosition(uiWindow *w, int x, int y)
-{
- if (!w) return;
-
- gtk_window_move(w->window, x, y);
-}
-
-void uiWindowPosition(uiWindow *w, int *x, int *y)
-{
- if (!w) return;
-
- int xx, yy;
- gtk_window_get_position(w->window, &xx, &yy);
- if (x) *x = xx;
- if (y) *y = yy;
-}
-
-uiUnixControlDefaultHandle(uiWindow)
-
-uiControl *uiWindowParent(uiControl *c)
-{
- return NULL;
-}
-
-void uiWindowSetParent(uiControl *c, uiControl *parent)
-{
- uiUserBugCannotSetParentOnToplevel("uiWindow");
-}
-
-static int uiWindowToplevel(uiControl *c)
-{
- return 1;
-}
-
-uiUnixControlDefaultVisible(uiWindow)
-
-static void uiWindowShow(uiControl *c)
-{
- uiWindow *w = uiWindow(c);
-
- // don't use gtk_widget_show_all() as that will show all children, regardless of user settings
- // don't use gtk_widget_show(); that doesn't bring to front or give keyboard focus
- // (gtk_window_present() does call gtk_widget_show() though)
- gtk_window_present(w->window);
-
- // set the size properly
- int width = w->width;
- int height = w->height;
- if (w->menubar)
- {
- GtkRequisition min, nat;
- int menuheight;
- gtk_widget_get_preferred_size(w->menubar, &min, &nat);
- menuheight = min.height;
- if (nat.height > menuheight) menuheight = nat.height;
- height += menuheight;
- }
- gtk_window_resize(w->window, width, height);
-}
-
-static void uiWindowSetFocus(uiControl* c)
-{
- gtk_window_present(GTK_WINDOW(uiWindow(c)->widget));
-}
-
-uiUnixControlDefaultHide(uiWindow)
-uiUnixControlDefaultEnabled(uiWindow)
-uiUnixControlDefaultEnable(uiWindow)
-uiUnixControlDefaultDisable(uiWindow)
-//uiUnixControlDefaultSetFocus(uiWindow)
-uiUnixControlDefaultSetMinSize(uiWindow)
-// TODO?
-uiUnixControlDefaultSetContainer(uiWindow)
-
-char *uiWindowTitle(uiWindow *w)
-{
- return uiUnixStrdupText(gtk_window_get_title(w->window));
-}
-
-void uiWindowSetTitle(uiWindow *w, const char *title)
-{
- gtk_window_set_title(w->window, title);
-}
-
-void uiWindowContentSize(uiWindow *w, int *width, int *height)
-{
- GtkAllocation allocation;
-
- gtk_widget_get_allocation(w->childHolderWidget, &allocation);
- *width = allocation.width;
- *height = allocation.height;
-}
-
-void uiWindowSetContentSize(uiWindow *w, int width, int height)
-{
- GtkAllocation childAlloc;
- gint winWidth, winHeight;
-
- // we need to resize the child holder widget to the given size
- // we can't resize that without running the event loop
- // but we can do gtk_window_set_size()
- // so how do we deal with the differences in sizes?
- // simple arithmetic, of course!
-
- // from what I can tell, the return from gtk_widget_get_allocation(w->window) and gtk_window_get_size(w->window) will be the same
- // this is not affected by Wayland and not affected by GTK+ builtin CSD
- // so we can safely juse use them to get the real window size!
- // since we're using gtk_window_resize(), use the latter
- gtk_window_get_size(w->window, &winWidth, &winHeight);
-
- // now get the child holder widget's current allocation
- gtk_widget_get_allocation(w->childHolderWidget, &childAlloc);
- // and punch that out of the window size
- winWidth -= childAlloc.width;
- winHeight -= childAlloc.height;
-
- // now we just need to add the new size back in
- winWidth += width;
- winHeight += height;
- // and set it
- // this will not move the window in my tests, so we're good
- gtk_window_resize(w->window, winWidth, winHeight);
-}
-
-int uiWindowMinimized(uiWindow *w)
-{
- // TODO!!
- return 0;
-}
-
-void uiWindowSetMinimized(uiWindow *w, int minimized)
-{
- if (minimized)
- gtk_window_iconify(w->window);
- else
- gtk_window_deiconify(w->window);
-}
-
-int uiWindowMaximized(uiWindow *w)
-{
- return gtk_window_is_maximized(w->window);
-}
-
-void uiWindowSetMaximized(uiWindow *w, int maximized)
-{
- if (maximized)
- gtk_window_maximize(w->window);
- else
- gtk_window_unmaximize(w->window);
-}
-
-
-int uiWindowFullscreen(uiWindow *w)
-{
- return w->fullscreen;
-}
-
-// TODO use window-state-event to track
-// TODO does this send an extra size changed?
-// TODO what behavior do we want?
-void uiWindowSetFullscreen(uiWindow *w, int fullscreen)
-{
- w->fullscreen = fullscreen;
- if (w->fullscreen)
- gtk_window_fullscreen(w->window);
- else
- gtk_window_unfullscreen(w->window);
-}
-
-void uiWindowOnContentSizeChanged(uiWindow *w, void (*f)(uiWindow *, void *), void *data)
-{
- w->onContentSizeChanged = f;
- w->onContentSizeChangedData = data;
-}
-
-void uiWindowOnClosing(uiWindow *w, int (*f)(uiWindow *, void *), void *data)
-{
- w->onClosing = f;
- w->onClosingData = data;
-}
-
-void uiWindowOnDropFile(uiWindow *w, void (*f)(uiWindow *, char *, void *), void *data)
-{
- w->onDropFile = f;
- w->onDropFileData = data;
-}
-
-void uiWindowOnGetFocus(uiWindow *w, void (*f)(uiWindow *, void *), void *data)
-{
- w->onGetFocus = f;
- w->onGetFocusData = data;
-}
-
-void uiWindowOnLoseFocus(uiWindow *w, void (*f)(uiWindow *, void *), void *data)
-{
- w->onLoseFocus = f;
- w->onLoseFocusData = data;
-}
-
-int uiWindowBorderless(uiWindow *w)
-{
- return gtk_window_get_decorated(w->window) == FALSE;
-}
-
-void uiWindowSetBorderless(uiWindow *w, int borderless)
-{
- gtk_window_set_decorated(w->window, borderless == 0);
-}
-
-// TODO save and restore expands and aligns
-void uiWindowSetChild(uiWindow *w, uiControl *child)
-{
- if (w->child != NULL) {
- uiControlSetParent(w->child, NULL);
- uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, TRUE);
- }
- w->child = child;
- if (w->child != NULL) {
- uiControlSetParent(w->child, uiControl(w));
- uiUnixControlSetContainer(uiUnixControl(w->child), w->childHolderContainer, FALSE);
- }
-}
-
-int uiWindowMargined(uiWindow *w)
-{
- return w->margined;
-}
-
-void uiWindowSetMargined(uiWindow *w, int margined)
-{
- w->margined = margined;
- setMargined(w->childHolderContainer, w->margined);
-}
-
-static void onDragDataReceived(GtkWidget* widget, GdkDragContext* ctx, gint x, gint y, GtkSelectionData* data, guint info, guint time, gpointer userdata)
-{
- uiWindow* w = (uiWindow*)userdata;
-
- if (gtk_selection_data_get_length(data) > 0 && gtk_selection_data_get_format(data) == 8)
- {
- gchar** files = gtk_selection_data_get_uris(data);
- if (files != NULL && files[0] != NULL)
- {
- // TODO: multi file support?
-
- gboolean success = FALSE;
-
- gchar* file = g_filename_from_uri(files[0], NULL, NULL);
- if (file)
- {
- if (w->onDropFile)
- w->onDropFile(w, file, w->onDropFileData);
-
- success = TRUE;
- g_free(file);
- }
-
-
- g_strfreev(files);
- gtk_drag_finish(ctx, success, FALSE, time);
- return;
- }
-
- if (files != NULL) g_strfreev(files);
- gtk_drag_finish(ctx, FALSE, FALSE, time);
- }
-}
-
-void uiWindowSetDropTarget(uiWindow* w, int drop)
-{
- if (!drop)
- {
- gtk_drag_dest_unset(w->widget);
- return;
- }
-
- GtkTargetEntry entry;
- entry.target = "text/uri-list";
- entry.flags = GTK_TARGET_OTHER_APP;
- entry.info = 1;
-
- // CHECKME: action copy?
- gtk_drag_dest_set(w->widget, GTK_DEST_DEFAULT_ALL, &entry, 1, GDK_ACTION_COPY|GDK_ACTION_MOVE);
-
- g_signal_connect(w->widget, "drag-data-received", G_CALLBACK(onDragDataReceived), w);
-}
-
-uiWindow *uiNewWindow(const char *title, int width, int height, int maximized, int hasMenubar, int resizable)
-{
- uiWindow *w;
-
- if (!resizable) maximized = 0;
-
- uiUnixNewControl(uiWindow, w);
-
- w->widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- w->container = GTK_CONTAINER(w->widget);
- w->window = GTK_WINDOW(w->widget);
-
- gtk_window_set_title(w->window, title);
- gtk_window_resize(w->window, width, height);
-
- w->vboxWidget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
- w->vboxContainer = GTK_CONTAINER(w->vboxWidget);
- w->vbox = GTK_BOX(w->vboxWidget);
-
- // set the vbox as the GtkWindow child
- gtk_container_add(w->container, w->vboxWidget);
-
- if (hasMenubar) {
- w->menubar = makeMenubar(uiWindow(w));
- gtk_container_add(w->vboxContainer, w->menubar);
- }
- else
- w->menubar = NULL;
-
- w->childHolderWidget = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
- w->childHolderContainer = GTK_CONTAINER(w->childHolderWidget);
- gtk_widget_set_hexpand(w->childHolderWidget, TRUE);
- gtk_widget_set_halign(w->childHolderWidget, GTK_ALIGN_FILL);
- gtk_widget_set_vexpand(w->childHolderWidget, TRUE);
- gtk_widget_set_valign(w->childHolderWidget, GTK_ALIGN_FILL);
- gtk_box_set_homogeneous(GTK_BOX(w->childHolderWidget), TRUE);
- gtk_container_add(w->vboxContainer, w->childHolderWidget);
-
- // show everything in the vbox, but not the GtkWindow itself
- gtk_widget_show_all(w->vboxWidget);
-
- // and connect our events
- g_signal_connect(w->widget, "delete-event", G_CALLBACK(onClosing), w);
- g_signal_connect(w->childHolderWidget, "size-allocate", G_CALLBACK(onSizeAllocate), w);
- g_signal_connect(w->widget, "focus-in-event", G_CALLBACK(onGetFocus), w);
- g_signal_connect(w->widget, "focus-out-event", G_CALLBACK(onLoseFocus), w);
-
- uiWindowOnClosing(w, defaultOnClosing, NULL);
- uiWindowOnContentSizeChanged(w, defaultOnPositionContentSizeChanged, NULL);
-
- uiWindowOnDropFile(w, NULL, NULL);
- uiWindowOnGetFocus(w, NULL, NULL);
- uiWindowOnLoseFocus(w, NULL, NULL);
-
- // normally it's SetParent() that does this, but we can't call SetParent() on a uiWindow
- // TODO we really need to clean this up, especially since see uiWindowDestroy() above
- g_object_ref(w->widget);
-
- gtk_window_set_resizable(w->window, resizable?TRUE:FALSE);
-
- w->width = width;
- w->height = height;
-
- if (maximized)
- gtk_window_maximize(w->window);
- else
- gtk_window_set_position(w->window, GTK_WIN_POS_CENTER);
-
- return w;
-}
-