06b97952836245dce43bba4ccd85ef32ca0b77db — Gregory Mullen 11 months ago 11e58ad master
refactor ui to make disabled the default & bt skel
M .gitignore => .gitignore +5 -0
@@ 3,6 3,11 @@
 *.mp4
 *.o
 *.bak
+*.txt
+*.out
+*.otf
+
+3rd-party-includes/**
 
 hudtds
 

M Makefile => Makefile +5 -3
@@ 8,12 8,13 @@ LD = arm-linux-gnueabihf-ld
 # LD = clang
 
 OBJ = hud.o
-OBJ += wayland.o wl/info.o wl/keyboard.o wl/touch.o wl/draw.o wl/ui.o wl/text.o wl/ivi.o wl/seat.o
-OBJ += gps.o
+OBJ += ui.o
+OBJ += wayland.o wl/info.o wl/keyboard.o wl/touch.o wl/draw.o  wl/text.o wl/ivi.o wl/seat.o
+OBJ += gps.o bluetooth.o
 OBJ += audio.o audio_search.o
 
-
 OBJ += gui/root.o gui/nav.o gui/notifier.o gui/onscreenkeys.o
+OBJ += gui/settings_gui.o
 OBJ += gui/gps_gui.o
 OBJ += gui/music.o gui/music_tracks.o gui/music_buttons.o gui/music_artists.o gui/music_albums.o
 


@@ 48,6 49,7 @@ LIBS   +=  -lwayland-ivi-shell-client -lwayland-ivi-client
 LIBS   +=  -lwayland-client
 LIBS   +=  -lavcodec -lavutil -lavformat -lswresample -lasound
 LIBS   +=  -lgps
+LIBS   +=  -lbluetooth
 LIBS   +=  -lffi -ldl -lrt -lpthread -lm
 
 %.o: %.c %.h

M README.md => README.md +7 -0
@@ 1,2 1,9 @@
 
+The following isn't likely to help you, but here's some various things I've
+learned working on this project.
+
+The gui suffix is appended to files that exist in other directories with the
+same name. I was getting some odd link time warnings, and this was an easy
+obvious solution.
+
 The 2016 MX-5 uses the ffmpeg-1.1 release for it's libav... libs

A bluetooth.c => bluetooth.c +74 -0
@@ 0,0 1,74 @@
+#include "bluetooth.h"
+
+#include "hud.h"
+#include "log.h"
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+#include <pthread.h>
+#include <time.h>
+
+
+static void *bluetooth_thread(void *p)
+{
+    (void) p;
+
+    int max_rsp = 255;
+    inquiry_info *ii = malloc(max_rsp * sizeof(inquiry_info));
+    if (!ii) {
+        LOG_F("Unable to malloc for inquiry_info\n");
+        exit(2);
+    }
+    int dev_id = hci_devid("C4:BE:84:6F:F8:EE");
+    int sock = hci_open_dev(dev_id);
+    if (dev_id < 0 || sock < 0) {
+        perror("opening socket");
+        exit(1);
+    }
+
+    while (1) {
+        // struct timespec __ts_nanosleep = { .tv_nsec = _TENTH_SEC};
+        // nanosleep(&__ts_nanosleep, NULL);
+        sleep(3);
+
+        LOG_E("Starting BT scan\n");
+        int num_rsp = hci_inquiry(dev_id, 6, max_rsp, NULL, &ii, IREQ_CACHE_FLUSH);
+        LOG_E("\nBT scan done, got %i\n\n", num_rsp);
+
+        if ( num_rsp < 0 ) {
+            perror("hci_inquiry");
+        }
+
+        char addr[19] = { 0 };
+        char name[248] = { 0 };
+        for (int i = 0; i < num_rsp; i++) {
+            ba2str(&(ii+i)->bdaddr, addr);
+            memset(name, 0, sizeof(name));
+            if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name), name, 0) < 0) {
+                strcpy(name, "[unknown]");
+            }
+
+            LOG_E("%s  %s\n", addr, name);
+        }
+
+        free(ii);
+        close(sock);
+    }
+
+    return NULL;
+}
+
+
+void bluetooth_thread_start(void)
+{
+    LOG_E("gps thread starting up\n");
+
+    pthread_t t;
+    pthread_create(&t, NULL, bluetooth_thread, NULL);
+}

A bluetooth.h => bluetooth.h +8 -0
@@ 0,0 1,8 @@
+#ifndef _HUD_BLUETOOTH_H_
+#define _HUD_BLUETOOTH_H_
+
+
+void bluetooth_thread_start(void);
+
+
+#endif // _HUD_BLUETOOTH_H_

M gps.c => gps.c +0 -6
@@ 10,13 10,10 @@
 #include <gps.h>
 #include <errno.h>
 
-#define _TENTH_SEC 1000 * 1000 * 100
-
 
 static bool gps_running = false;
 static bool gps_exit = false;
 
-
 static struct hud_gps_data hud_gps_data;
 
 


@@ 52,9 49,7 @@ static void *gps_thread(void *p)
         LOG_E("Early exit from gps thread!\n");
         return NULL;
     }
-
     struct gps_data_t *gps = p;
-    LOG_E("pointer %p\n", gps);
 
     gps_running = true;
 


@@ 111,7 106,6 @@ void gps_thread_start(void)
     LOG_E("gps thread starting up\n");
 
     struct gps_data_t *gps  = gps_init();
-    LOG_E("pointer %p\n", gps);
     pthread_create(&t, NULL, gps_thread, gps);
 }
 

A gui/bluetooth.c => gui/bluetooth.c +45 -0
@@ 0,0 1,45 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+int main(int argc, char **argv)
+{
+    inquiry_info *ii = NULL;
+    int max_rsp, num_rsp;
+    int dev_id, sock, len, flags;
+    int i;
+    char addr[19] = { 0 };
+    char name[248] = { 0 };
+
+    dev_id = hci_get_route(NULL);
+    sock = hci_open_dev( dev_id );
+    if (dev_id < 0 || sock < 0) {
+        perror("opening socket");
+        exit(1);
+    }
+
+    len  = 8;
+    max_rsp = 255;
+    flags = IREQ_CACHE_FLUSH;
+    ii = (inquiry_info*)malloc(max_rsp * sizeof(inquiry_info));
+
+    num_rsp = hci_inquiry(dev_id, len, max_rsp, NULL, &ii, flags);
+    if( num_rsp < 0 ) perror("hci_inquiry");
+
+    for (i = 0; i < num_rsp; i++) {
+        ba2str(&(ii+i)->bdaddr, addr);
+        memset(name, 0, sizeof(name));
+        if (hci_read_remote_name(sock, &(ii+i)->bdaddr, sizeof(name),
+            name, 0) < 0)
+        strcpy(name, "[unknown]");
+        printf("%s  %s\n", addr, name);
+    }
+
+    free( ii );
+    close( sock );
+    return 0;
+}

M gui/gps_gui.c => gui/gps_gui.c +11 -11
@@ 1,6 1,6 @@
 #include "gps_gui.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/text.h"
 #include "../wl/draw.h"
 #include "../log.h"


@@ 32,29 32,29 @@ static void draw_gps_data(struct ui_panel *p, int32_t x, int32_t y, int32_t w, i
 
     struct hud_gps_data *data = gps_get_data();
     if (!data) {
-        text_draw_string("ERROR, unable to get gps data!", x + 2, y + 20);
+        text_string("ERROR, unable to get gps data!", x + 2, y + 20);
         return;
     }
 
     static char str[1024] = {0};
 
     snprintf(str, sizeof str, "LAT: %lf", data->lat);
-    text_draw_string(str, x + 2, y + 10);
+    text_string(str, x + 2, y + 10);
 
     snprintf(str, sizeof str, "LON: %lf", data->lon);
-    text_draw_string(str, x + 2, y + 30);
+    text_string(str, x + 2, y + 30);
 
     snprintf(str, sizeof str, "ALT: %lf", data->alt);
-    text_draw_string(str, x + 2, y + 50);
+    text_string(str, x + 2, y + 50);
 
     snprintf(str, sizeof str, "Ground Speed: %.2lf", data->gnd_speed);
-    text_draw_string(str, x + 2, y + 90);
+    text_string(str, x + 2, y + 90);
 
     snprintf(str, sizeof str, "Climb Speed: %.2lf", data->vert_speed);
-    text_draw_string(str, x + 2, y + 120);
+    text_string(str, x + 2, y + 120);
 
     snprintf(str, sizeof str, "Satellites: %i (%i)", data->satellites_visible, data->satellites_used);
-    text_draw_string(str, x + 2, y + 150);
+    text_string(str, x + 2, y + 150);
 
     free(data);
 }


@@ 91,7 91,7 @@ struct ui_panel gps_data = {
     .name = "gps_frame",
     .draw = draw_gps_data,
     .focused = false,
-    .disabled = false,
+    .enabled = true,
     .pos_x = 0,
     .pos_y = 0,
     .width = 530,


@@ 102,7 102,7 @@ struct ui_panel gps_globe = {
     .name = "gps_frame",
     .draw = draw_gps_globe,
     .focused = false,
-    .disabled = false,
+    .enabled = true,
     .pos_x = 530,
     .pos_y = 0,
     .width = 270,


@@ 113,7 113,7 @@ struct ui_panel gps_frame = {
     .name = "gps_frame",
     .draw = draw_gps_frame,
     .focused = false,
-    .disabled = true,
+    .enabled = false,
     .pos_x = 0,
     .pos_y = 0,
     .children = (struct ui_panel*[]) {

M gui/music.c => gui/music.c +12 -10
@@ 1,6 1,7 @@
 #include "music.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
+
 #include "../wl/draw.h"
 #include "../wl/text.h"
 #include "../wl/keyboard.h"


@@ 29,9 30,9 @@ static void draw_music_playing(struct ui_panel *p, int32_t x, int32_t y, int32_t
 
     struct track_data *track = audio_track_get_current();
     if (track) {
-        text_draw_string(track->filename, x + 3, y + 3);
+        text_string(track->filename, x + 3, y + 3);
     } else {
-        text_draw_string("No Song Playing", x + 3, y + 3);
+        text_string("No Song Playing", x + 3, y + 3);
     }
 }
 


@@ 57,6 58,7 @@ struct ui_panel music_track_playing = {
     .name = "music entry playing",
     .draw = draw_music_playing,
     .k_dn = music_playing_kdn,
+    .enabled = true,
     .pos_x = 0,
     .pos_y = 0,
     .height = 60,


@@ 95,23 97,23 @@ static bool frame_key_down_main(struct ui_panel *panel, const uint32_t key, cons
         }
         case MZD_KEYMAP_DPAD_LEFT: {
             LOG_T("music_frame_keydown dpad left\n");
-            if (music_buttons_frame.focused == true) {
+            if (music_tracks_frame.focused == true) {
                 return false;
             } else {
-                music_buttons_frame.focused = true;
+                music_tracks_frame.focused = true;
                 music_track_playing.focused = false;
-                music_tracks_frame.focused = false;
+                music_buttons_frame.focused = false;
                 return true;
             }
         }
         case MZD_KEYMAP_DPAD_RIGHT: {
             LOG_T("music_frame_keydown dpad right\n");
-            if (music_tracks_frame.focused == true) {
+            if (music_buttons_frame.focused == true) {
                 return false;
             } else {
-                music_tracks_frame.focused = true;
+                music_buttons_frame.focused = true;
                 music_track_playing.focused = false;
-                music_buttons_frame.focused = false;
+                music_tracks_frame.focused = false;
                 return true;
             }
         }


@@ 128,7 130,7 @@ struct ui_panel music_frame = {
     .height = -80,
     .k_dn = frame_key_down_main,
     .focused = true,
-    .disabled = false,
+    .enabled = true,
 
     .children = (struct ui_panel*[]) {
         (struct ui_panel*)&music_track_playing,

M gui/music.h => gui/music.h +0 -2
@@ 1,8 1,6 @@
 #ifndef _HUDTDS_GUI_MUSIC_
 #define _HUDTDS_GUI_MUSIC_
 
-#include "../wl/ui.h"
-
 extern struct ui_panel music_frame;
 extern struct ui_panel music_buttons_frame;
 extern struct ui_panel music_tracks_frame;

M gui/music_albums.c => gui/music_albums.c +5 -4
@@ 1,6 1,6 @@
 #include "music.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/draw.h"
 #include "../wl/text.h"
 #include "../wl/keyboard.h"


@@ 37,7 37,7 @@ static void draw_music_album(struct ui_panel *p, int32_t x, int32_t y, int32_t w
         draw_box_c(x, y, w, y + p->height, p->color);
     }
 
-    text_draw_string(album->name, x + 3, y + 3);
+    text_string(album->name, x + 3, y + 3);
 }
 
 


@@ 194,12 194,13 @@ static bool frame_key_down(struct ui_panel *p, const uint32_t key, const uint32_
 struct ui_panel music_albums_frame = {
     .type = PANEL_LIST,
     .name = "music artist frame",
-    .pos_x = 80,
+    .pos_x = 0,
     .pos_y = 60,
+    .width = -80,
     .height = -80,
     .k_dn = frame_key_down,
     .focused = false,
-    .disabled = true,
+    .enabled = false,
     .children = (struct ui_panel*[]) {
         (struct ui_panel*)&album_0,
         (struct ui_panel*)&album_1,

M gui/music_artists.c => gui/music_artists.c +5 -4
@@ 1,6 1,6 @@
 #include "music.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/draw.h"
 #include "../wl/text.h"
 #include "../wl/keyboard.h"


@@ 38,7 38,7 @@ static void draw_music_track(struct ui_panel *p, int32_t x, int32_t y, int32_t w
         draw_box_c(x, y, w, y + p->height, p->color);
     }
 
-    text_draw_string(artist->name, x + 3, y + 3);
+    text_string(artist->name, x + 3, y + 3);
 }
 
 


@@ 197,12 197,13 @@ static bool frame_key_down(struct ui_panel *p, const uint32_t key, const uint32_
 struct ui_panel music_artists_frame = {
     .type = PANEL_LIST,
     .name = "music artist frame",
-    .pos_x = 80,
+    .pos_x = 0,
     .pos_y = 60,
+    .width = -80,
     .height = -80,
     .k_dn = frame_key_down,
     .focused = false,
-    .disabled = true,
+    .enabled = false,
     .children = (struct ui_panel*[]) {
         (struct ui_panel*)&music_artist_0,
         (struct ui_panel*)&music_artist_1,

M gui/music_buttons.c => gui/music_buttons.c +65 -21
@@ 2,16 2,16 @@
 
 #include "../log.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/draw.h"
 #include "../wl/keyboard.h"
 
 
-static void music_btn_disable_all(void)
+static void _disable_all(void)
 {
-    music_tracks_frame.disabled = true;
+    music_tracks_frame.enabled = false;
     music_tracks_frame.focused = false;
-    music_artists_frame.disabled = true;
+    music_artists_frame.enabled = false;
     music_artists_frame.focused = false;
 
     music_buttons_frame.focused = false;


@@ 21,7 21,6 @@ static void music_btn_disable_all(void)
 static bool music_btn_tracks(struct ui_panel *p, const int mx, const int my, const int x, const int y, const uint32_t w, uint32_t h,
     const uint32_t id, const uint32_t serial)
 {
-    (void) p;
     (void) mx;
     (void) my;
     (void) x;


@@ 32,9 31,11 @@ static bool music_btn_tracks(struct ui_panel *p, const int mx, const int my, con
     (void) serial;
     LOG_N("Music show tracks\n");
 
-    music_btn_disable_all();
-    music_tracks_frame.disabled = false;
+    p->draw_needed = true;
+    _disable_all();
+    music_tracks_frame.enabled = true;
     music_tracks_frame.focused = true;
+
     return true;
 }
 


@@ 42,7 43,6 @@ static bool music_btn_tracks(struct ui_panel *p, const int mx, const int my, con
 static bool music_btn_artists(struct ui_panel *p, const int mx, const int my, const int x, const int y, const uint32_t w, uint32_t h,
     const uint32_t id, const uint32_t serial)
 {
-    (void) p;
     (void) mx;
     (void) my;
     (void) x;


@@ 53,13 53,11 @@ static bool music_btn_artists(struct ui_panel *p, const int mx, const int my, co
     (void) serial;
     LOG_N("Music Show artists\n");
 
-    music_btn_disable_all();
-    music_artists_frame.disabled = false;
+    p->draw_needed = true;
+    _disable_all();
+    music_artists_frame.enabled = true;
     music_artists_frame.focused = true;
 
-    music_btn_disable_all();
-    music_artists_frame.disabled = false;
-    music_artists_frame.focused = true;
     return true;
 }
 


@@ 67,7 65,6 @@ static bool music_btn_artists(struct ui_panel *p, const int mx, const int my, co
 static bool music_btn_albums(struct ui_panel *p, const int mx, const int my, const int x, const int y, const uint32_t w, uint32_t h,
     const uint32_t id, const uint32_t serial)
 {
-    (void) p;
     (void) mx;
     (void) my;
     (void) x;


@@ 78,9 75,11 @@ static bool music_btn_albums(struct ui_panel *p, const int mx, const int my, con
     (void) serial;
     LOG_N("Music Show Albums\n");
 
-    music_btn_disable_all();
-    music_albums_frame.disabled = false;
+    p->draw_needed = true;
+    _disable_all();
+    music_albums_frame.enabled = true;
     music_albums_frame.focused = true;
+
     return true;
 }
 


@@ 100,9 99,50 @@ static void draw_button(struct ui_panel *p, int32_t x, int32_t y, int32_t w, int
 }
 
 
+static void d_artist(struct ui_panel *p, int32_t x, int32_t y, int32_t w, int32_t h)
+{
+    x = p->pos_x < 0 ? w + p->pos_x : x + p->pos_x;
+    y = p->pos_y < 0 ? h + p->pos_y : y + p->pos_y;
+    w = p->width <= 0 ? w + p->width : x + p->width;
+    h = p->height <= 0 ? h + p->height : y + p->height;
+
+    if (p->focused && music_buttons_frame.focused) {
+        draw_square_c(x, y, w, h, p->color);
+    } else {
+        draw_box_c(x, y, w, h, p->color);
+    }
+
+    draw_set_clipping_box(x, y, w, h);
+
+    draw_circle_radius_c(x + (w - x) / 2, h, 20, 0xffffffff);
+    draw_circle_radius_c(x + (w - x) / 2, h - (w - x * 0.75), (w - x) * 0.33, 0xffffffff);
+
+    draw_reset_clipping_box();
+}
+
+
+static void d_album(struct ui_panel *p, int32_t x, int32_t y, int32_t w, int32_t h)
+{
+    x = p->pos_x < 0 ? w + p->pos_x : x + p->pos_x;
+    y = p->pos_y < 0 ? h + p->pos_y : y + p->pos_y;
+    w = p->width <= 0 ? w + p->width : x + p->width;
+    h = p->height <= 0 ? h + p->height : y + p->height;
+
+    if (p->focused && music_buttons_frame.focused) {
+        draw_square_c(x, y, w, h, p->color);
+    } else {
+        draw_box_c(x, y, w, h, p->color);
+    }
+
+    draw_circle_radius_c(x + (w - x) / 2, y + (h - y) / 2, 20, 0xffffffff);
+    draw_circle_radius_c(x + (w - x) / 2, y + (h - y) / 2, 5,  0xff000000);
+}
+
+
 struct ui_panel music_btn_0 = {
     .name = "music_btn_0",
     .color = 0xff0000ff,
+    .enabled = true,
     .draw = draw_button,
     .t_dn = music_btn_tracks,
     .pos_x = 0,


@@ 112,9 152,10 @@ struct ui_panel music_btn_0 = {
 };
 
 struct ui_panel music_btn_1 = {
+    .name = "Music Button Artist",
     .color = 0xff00ff00,
-    .name = "music_btn_1",
-    .draw = draw_button,
+    .enabled = true,
+    .draw = d_artist,
     .t_dn = music_btn_artists,
     .pos_x = 0,
     .pos_y = 80 * 1,


@@ 123,9 164,10 @@ struct ui_panel music_btn_1 = {
 };
 
 struct ui_panel music_btn_2 = {
-    .name = "music_btn_2",
+    .name = "Music Button Album",
     .color = 0xffff0000,
-    .draw = draw_button,
+    .enabled = true,
+    .draw = d_album,
     .t_dn = music_btn_albums,
     .pos_x = 0,
     .pos_y = 80 * 2,


@@ 136,6 178,7 @@ struct ui_panel music_btn_2 = {
 struct ui_panel music_btn_3 = {
     .name = "music_btn_3",
     .color = 0xffff00ff,
+    .enabled = true,
     .draw = draw_button,
     .t_dn = music_btn_tracks,
     .pos_x = 0,


@@ 204,10 247,11 @@ static bool frame_key_down(struct ui_panel *p, const uint32_t key, const uint32_
 struct ui_panel music_buttons_frame = {
     .type = PANEL_LIST,
     .name = "music entry frame",
+    .enabled = true,
+    .k_dn = frame_key_down,
     .pos_x = -80,
     .pos_y = 60,
     .height = -80,
-    .k_dn = frame_key_down,
     .focused = false,
     .touch_focus = false,
     .children = (struct ui_panel*[]) {

M gui/music_tracks.c => gui/music_tracks.c +12 -4
@@ 1,6 1,6 @@
 #include "music.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/draw.h"
 #include "../wl/text.h"
 #include "../wl/keyboard.h"


@@ 75,13 75,14 @@ static void draw_music_track(struct ui_panel *p, int32_t x, int32_t y, int32_t w
     draw_box_depth_c(x, y, w, y + p->height, 2, 0xff440000);
 
     const struct track_data *track = track_get_pos(p->order);
-    text_draw_string_width(entry_text(track), x + 8, y + 8, w - 8);
+    text_string_width(entry_text(track), x + 8, y + 8, w - 8);
 }
 
 
 struct ui_panel music_track_0 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_0",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 0,


@@ 94,6 95,7 @@ struct ui_panel music_track_0 = {
 struct ui_panel music_track_1 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_1",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 40,


@@ 106,6 108,7 @@ struct ui_panel music_track_1 = {
 struct ui_panel music_track_2 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_2",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 80,


@@ 118,6 121,7 @@ struct ui_panel music_track_2 = {
 struct ui_panel music_track_3 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_3",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 120,


@@ 130,6 134,7 @@ struct ui_panel music_track_3 = {
 struct ui_panel music_track_4 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_4",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 160,


@@ 142,6 147,7 @@ struct ui_panel music_track_4 = {
 struct ui_panel music_track_5 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_5",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 200,


@@ 154,6 160,7 @@ struct ui_panel music_track_5 = {
 struct ui_panel music_track_6 = {
     .type = PANEL_LIST_ENTRY,
     .name = "music entry_6",
+    .enabled = true,
     .draw = draw_music_track,
     .pos_x = 0,
     .pos_y = 240,


@@ 232,12 239,13 @@ static bool frame_key_down(struct ui_panel *p, const uint32_t key, const uint32_
 struct ui_panel music_tracks_frame = {
     .type = PANEL_LIST,
     .name = "music entry frame",
+    .enabled = true,
+    .focused = true,
+    .k_dn = frame_key_down,
     .pos_x = 0,
     .pos_y = 60,
     .width = -80,
     .height = -80,
-    .k_dn = frame_key_down,
-    .focused = true,
     .children = (struct ui_panel*[]) {
         (struct ui_panel*)&music_track_0,
         (struct ui_panel*)&music_track_1,

M gui/nav.c => gui/nav.c +28 -19
@@ 2,7 2,7 @@
 
 #include "onscreenkeys.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/draw.h"
 
 #include "../log.h"


@@ 43,9 43,10 @@ static void draw_button(struct ui_panel *p, int32_t x, int32_t y, int32_t w, int
 #define NAV_BTW_H 65
 
 struct ui_panel nav_btn_0 = {
-    .draw = draw_button,
-    .color = 0xff888888,
     .name = "nav_btn_0",
+    .enabled = true,
+    .color = 0xff888888,
+    .draw = draw_button,
     .t_dn = touch_test_1,
     .pos_x = NAV_BTW_W * 0,
     .pos_y = 0,


@@ 54,9 55,10 @@ struct ui_panel nav_btn_0 = {
 };
 
 struct ui_panel nav_btn_1 = {
-    .draw = draw_button,
-    .color = 0xffff0000,
     .name = "nav_btn_1",
+    .enabled = true,
+    .color = 0xffff0000,
+    .draw = draw_button,
     .t_dn = touch_test_1,
     .pos_x =NAV_BTW_W * 1,
     .pos_y = 0,


@@ 65,9 67,10 @@ struct ui_panel nav_btn_1 = {
 };
 
 struct ui_panel nav_btn_2 = {
-    .draw = draw_button,
-    .color = 0xffffffff,
     .name = "nav_btn_2",
+    .enabled = true,
+    .color = 0xffffffff,
+    .draw = draw_button,
     .t_dn = touch_test_1,
     .pos_x = NAV_BTW_W * 2,
     .pos_y = 0,


@@ 76,9 79,10 @@ struct ui_panel nav_btn_2 = {
 };
 
 struct ui_panel nav_btn_3 = {
-    .draw = draw_button,
-    .color = 0xff00ff00,
     .name = "nav_btn_3",
+    .enabled = true,
+    .color = 0xff00ff00,
+    .draw = draw_button,
     .t_dn = touch_test_1,
     .pos_x = NAV_BTW_W * 3,
     .pos_y = 0,


@@ 87,9 91,10 @@ struct ui_panel nav_btn_3 = {
 };
 
 struct ui_panel nav_btn_4 = {
-    .draw = draw_button,
-    .color = 0xff00ffff,
     .name = "nav_btn_4",
+    .enabled = true,
+    .color = 0xff00ffff,
+    .draw = draw_button,
     .t_dn = touch_test_1,
     .pos_x = NAV_BTW_W * 4,
     .pos_y = 0,


@@ 98,9 103,10 @@ struct ui_panel nav_btn_4 = {
 };
 
 struct ui_panel nav_btn_5 = {
-    .draw = draw_button,
-    .color = 0xffff00ff,
     .name = "nav_btn_5",
+    .enabled = true,
+    .color = 0xffff00ff,
+    .draw = draw_button,
     .t_dn = touch_test_1,
     .pos_x = NAV_BTW_W * 5,
     .pos_y = 0,


@@ 143,16 149,17 @@ static bool tgl_keys(struct ui_panel *p, const int mx, const int my, const int x
     (void) id;
     (void) serial;
 
-    onscreenkey_frame.disabled = !onscreenkey_frame.disabled;
+    onscreenkey_frame.enabled = !onscreenkey_frame.enabled;
 
     return true;
 }
 
 
 static struct ui_panel nav_btn_8 = {
-    .draw = draw_button,
-    .color = 0xff8888ff,
     .name = "nav_btn_8",
+    .color = 0xff8888ff,
+    .enabled = true,
+    .draw = draw_button,
     .t_dn = tgl_keys,
     .pos_x = NAV_BTW_W * 8,
     .pos_y = 0,


@@ 181,9 188,10 @@ static bool touch_exit(struct ui_panel *p, const int mx, const int my, const int
 
 
 struct ui_panel nav_btn_9 = {
-    .draw = draw_button,
-    .color = 0xff333333,
     .name = "nav_btn_9",
+    .color = 0xff333333,
+    .enabled = true,
+    .draw = draw_button,
     .t_dn = touch_exit,
     .pos_x = NAV_BTW_W * 9,
     .pos_y = 0,


@@ 193,9 201,10 @@ struct ui_panel nav_btn_9 = {
 
 
 struct ui_panel nav_frame = {
-    .draw = draw_button,
     .type = PANEL_FRAME,
     .name = "nav frame",
+    .enabled = true,
+    .draw = draw_button,
     .pos_x = 0,
     .pos_y = -NAV_BTW_H,
     .height = NAV_BTW_H,

M gui/notifier.c => gui/notifier.c +5 -2
@@ 2,7 2,8 @@
 
 
 #include "../log.h"
-#include "../wl/ui.h"
+#include "../ui.h"
+
 #include "../wl/draw.h"
 #include "../wl/text.h"
 


@@ 39,7 40,8 @@ static void draw_timedate(struct ui_panel *p, int32_t x, int32_t y, int32_t w, i
     h = p->height <= 0 ? h + p->height : y + p->height;
 
     // draw_box_c(x, y, w, h, p->color);
-    text_draw_string("20:48", x + 3, y + 3);
+    // text_string_ralign("20:48", w, y + 3);
+    text_string_ralign("20:48", x + 3, y + 3);
 }
 
 


@@ 68,6 70,7 @@ struct ui_panel notifier = {
     .pos_x = 0,
     .pos_y = 0,
     .height = 35,
+    .enabled = true,
     .children = (struct ui_panel*[]){
         &notifications,
         &time_date,

M gui/onscreenkeys.c => gui/onscreenkeys.c +2 -2
@@ 1,6 1,6 @@
 #include "onscreenkeys.h"
 
-#include "../wl/ui.h"
+#include "../ui.h"
 
 #include <stdlib.h>
 


@@ 220,7 220,7 @@ static struct ui_panel onscreenkey_row_3 = {
 struct ui_panel onscreenkey_frame = {
     .type = PANEL_FRAME,
     .name = "onscreenkeys frame",
-    .disabled = true,
+    .enabled = false,
 
     .pos_x = 0,
     .pos_y = 0,

M gui/root.c => gui/root.c +30 -12
@@ 4,10 4,11 @@
 #include "music.h"
 #include "nav.h"
 #include "gps_gui.h"
+#include "settings_gui.h"
 // #include "onscreenkeys.h"
 
 #include "../wl/keyboard.h"
-#include "../wl/ui.h"
+#include "../ui.h"
 #include "../wl/text.h"
 #include "../wl/draw.h"
 #include "../log.h"


@@ 23,10 24,23 @@ static void draw_root_frame(struct ui_panel *p, int32_t x, int32_t y, int32_t w,
     (void) h;
 
     draw_square(x, y, w, h);
-    text_draw_string("HudTds!", 2, 2);
+    text_string("HudTds!", 2, 2);
 }
 
 
+
+static void _disable_all(struct ui_panel *main)
+{
+    struct ui_panel **children = main->children;
+    struct ui_panel *p;
+
+    while ((p = *children++)) {
+        p->enabled = false;
+        p->focused = false;
+    }
+
+}
+
 static bool main_kdn(struct ui_panel *p, const uint32_t key, const uint32_t s)
 {
     (void) s;


@@ 35,21 49,23 @@ static bool main_kdn(struct ui_panel *p, const uint32_t key, const uint32_t s)
     switch (key) {
         case MZD_KEYMAP_EXT_MUSIC: {
             LOG_E("main frame music btn\n");
-            music_frame.disabled = false;
+            _disable_all(p);
+            music_frame.enabled = true;
             music_frame.focused = true;
-
-            gps_frame.disabled = true;
-            gps_frame.focused = false;
-
             return true;
         }
         case MZD_KEYMAP_EXT_NAV: {
             LOG_E("main frame nav btn\n");
-            gps_frame.disabled = false;
+            _disable_all(p);
+            gps_frame.enabled = true;
             gps_frame.focused = true;
-
-            music_frame.disabled = true;
-            music_frame.focused = false;
+            return true;
+        }
+        case MZD_KEYMAP_EXT_HOME: {
+            LOG_E("main frame nav btn\n");
+            _disable_all(p);
+            settings_frame.enabled = true;
+            settings_frame.focused = true;
             return true;
         }
     }


@@ 57,10 73,11 @@ static bool main_kdn(struct ui_panel *p, const uint32_t key, const uint32_t s)
 }
 
 
-struct ui_panel main_frame = {
+static struct ui_panel main_frame = {
     .name = "main frame",
     .draw = draw_root_frame,
     .focused = true,
+    .enabled = true,
     .k_dn = main_kdn,
     .pos_x = 0,
     .pos_y = 35,


@@ 80,6 97,7 @@ struct ui_panel root_panel = {
     .width = WIDTH - 1,
     .height = HEIGHT - 1,
     .focused = true,
+    .enabled = true,
 
     .children = (struct ui_panel*[]){
         &notifier,

A gui/settings_gui.c => gui/settings_gui.c +20 -0
@@ 0,0 1,20 @@
+#include "settings_gui.h"
+
+#include "../ui.h"
+
+#include <stddef.h>
+
+struct ui_panel settings_frame = {
+    .type = PANEL_FRAME,
+    .name = "settings frame",
+    .pos_x = 0,
+    .pos_y = 0,
+    .height = -80,
+    .focused = false,
+    .enabled = false,
+
+    .children = (struct ui_panel*[]) {
+        NULL
+    }
+};
+

A gui/settings_gui.h => gui/settings_gui.h +6 -0
@@ 0,0 1,6 @@
+#ifndef _HUDTDS_GUI_SETTINGS_
+#define _HUDTDS_GUI_SETTINGS_
+
+extern struct ui_panel settings_frame;
+
+#endif // _HUDTDS_GUI_SETTINGS_

M hud.c => hud.c +3 -0
@@ 5,6 5,7 @@
 
 #include "audio.h"
 #include "gps.h"
+#include "bluetooth.h"
 
 #include <stdlib.h>
 #include <stdbool.h>


@@ 41,6 42,8 @@ int main(void)
     LOG_D("Starting GPS Thread\n");
     gps_thread_start();
 
+    // bluetooth_thread_start();
+
     while (!done) {
         if (do_wayland() < 0) {
             LOG_E("Main loop error");

M hud.h => hud.h +4 -0
@@ 10,6 10,10 @@
 
 #define _POSIX_C_SOURCE 200809L
 
+#define _TENTH_SEC 1000 * 1000 * 100
+#define _TEN_SEC 1000 * 1000 * 1000 * 10
+
+
 extern char *strdup (__const char *__s);
 
 typedef unsigned int uint;

R wl/ui.c => ui.c +10 -9
@@ 1,13 1,13 @@
 #include "ui.h"
 
-#include "draw.h"
-#include "text.h"
+#include "wl/draw.h"
+#include "wl/text.h"
 
-#include "../hud.h"
-#include "../log.h"
-#include "../wayland.h"
+#include "hud.h"
+#include "log.h"
+#include "wayland.h"
 
-#include "../gui/root.h"
+#include "gui/root.h"
 
 #include <stdlib.h>
 


@@ 34,7 34,7 @@ bool ui_touch_down(struct ui_panel *panel, const int mx, const int my, const int
     if (children) {
         struct ui_panel *p;
         while ((p = *children++)) {
-            if (p->disabled) {
+            if (!p->enabled) {
                 continue;
             }
 


@@ 69,7 69,7 @@ bool ui_touch_up(struct ui_panel *panel, const int x, const int y, const uint32_
     if (children) {
         struct ui_panel *p;
         while ((p = *children++)) {
-            if (p->disabled) {
+            if (!p->enabled) {
                 continue;
             }
 


@@ 179,9 179,10 @@ bool ui_panel_draw(struct ui_panel *panel, int32_t x, int32_t y, int32_t w, int3
         int32_t l_x = x, l_y = y, l_w = w, l_h = h;
         XYWH_TO_CHILD();
         while ((p = *--children)) {
-            if (!p->disabled) {
+            if (p->enabled) {
                 redraw |= ui_panel_draw(p, l_x, l_y, l_w, l_h);
             }
+
             if (p == first) {
                 break;
             }

R wl/ui.h => ui.h +1 -2
@@ 25,7 25,6 @@ typedef enum {
     PANEL_LIST,
     PANEL_LIST_ENTRY,
 
-
     PANEL_OTHER,
     PANEL_MAX = 255
 } PANEL_TYPE;


@@ 49,7 48,7 @@ struct ui_panel {
 
     bool focused;
     bool touch_focus;
-    bool disabled;
+    bool enabled;
 
     int32_t pos_x;
     int32_t pos_y;

M wayland.c => wayland.c +11 -3
@@ 3,7 3,7 @@
 #include "hud.h"
 #include "log.h"
 
-#include "wl/ui.h"
+#include "ui.h"
 #include "wl/ivi.h"
 #include "wl/seat.h"
 #include "wl/draw.h"


@@ 117,10 117,9 @@ static struct surface *init_memory_pool(struct surface *surface)
         exit(1);
     }
 
-    LOG_E("write\n");
     memset(surface->memory, 0xff, surface->mem_capacity);
-
     draw_swap_buffer(root_surface->memory);
+    LOG_E("write\n");
 
     // // memset(surface->memory, 0x00, HEIGHT * STRIDE);
     // uint32_t *p = surface->memory;


@@ 251,6 250,14 @@ struct wl_display *init_wayland(void)
     wl_shell_surface_set_toplevel(root_surface->shell_surface);
     wl_shell_surface_set_fullscreen(root_surface->shell_surface, WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT, 0, NULL);
 
+    // HACK FIXME leave this here until we handle partial draws correctly
+    ui_iter(NULL);
+    hud_surface_damage(0, 0, WIDTH, HEIGHT);
+    hud_surface_commit();
+    ui_iter(NULL);
+    hud_surface_damage(0, 0, WIDTH, HEIGHT);
+    hud_surface_commit();
+
     return display;
 }
 


@@ 258,6 265,7 @@ struct wl_display *init_wayland(void)
 int do_wayland(void)
 {
     if (ui_iter(NULL)) {
+        // FIXME ui_iter should be calling surface damage, only when
         hud_surface_damage(0, 0, WIDTH, HEIGHT);
         hud_surface_commit();
     }

M wl/draw.c => wl/draw.c +7 -10
@@ 37,19 37,16 @@ static uint32_t *draw_buffer = NULL;
 }  while(0)
 
 
-struct clipping_box_t {
+static struct clipping_box_t {
     bool set;
     int32_t x;
     int32_t y;
     int32_t w;
     int32_t h;
-};
+} clip_box = {0};
 
 
-static struct clipping_box_t clip_box = {0};
-
-
-void reset_cliping_box()
+void draw_reset_clipping_box(void)
 {
     if (clip_box.set) {
         // do cliping box memcpy


@@ 63,10 60,10 @@ void reset_cliping_box()
 }
 
 
-void set_cliping_box(int32_t x, int32_t y, int32_t w, int32_t h)
+void draw_set_clipping_box(int32_t x, int32_t y, int32_t w, int32_t h)
 {
     if (x == w || y == h) {
-        reset_cliping_box();
+        draw_reset_clipping_box();
         return;
     }
 


@@ 288,8 285,8 @@ void draw_circle_radius_c(int32_t x, int32_t y, int32_t radius, uint32_t c)
     double r = radius - 0.5;
     int32_t ax = x - r;
     int32_t ay = y - r;
-    for (int i = 0; i < r * 2; i++) {
-        for (int j = 0; j < r * 2; j++) {
+    for (int i = 0; i < radius * 2; i++) {
+        for (int j = 0; j < radius * 2; j++) {
             double di = i - r;
             double dj = j - r;
             double mix = sqrtf(di * di + dj * dj) - r + 0.5;

M wl/draw.h => wl/draw.h +3 -0
@@ 5,6 5,9 @@
 #include <stdbool.h>
 
 
+void draw_reset_clipping_box(void);
+void draw_set_clipping_box(int32_t x, int32_t y, int32_t w, int32_t h);
+
 void draw_swap_buffer(uint32_t *buffer);
 
 bool draw_pixel(int32_t x, int32_t y, uint32_t c);

M wl/ivi.c => wl/ivi.c +1 -1
@@ 75,7 75,7 @@ static void ivi_shell_create(void *data, struct wl_interface *interface, char *n
             wl_proxy_marshal(ani_grp, IVI_SHELL_ANIMATION_GROUP_ANIMATE_CUBICBEZIER2d, name,
                 IVI_SHELL_ANIMATE_CUBICEBZIER2D_POSITION, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0);
 
-            wl_fixed_t o = wl_fixed_from_double(2);
+            wl_fixed_t o = wl_fixed_from_double(1);
             wl_proxy_marshal(ani_grp, IVI_SHELL_ANIMATION_GROUP_ANIMATE_CUBICBEZIER2d, name,
                 IVI_SHELL_ANIMATE_CUBICEBZIER2D_SET_ORIGIN, 0, 0, o, o, o, o, o, o, 0, 0);
             wl_fixed_t w = wl_fixed_from_double(WIDTH);

M wl/keyboard.c => wl/keyboard.c +1 -1
@@ 1,6 1,6 @@
 #include "keyboard.h"
 
-#include "ui.h"
+#include "../ui.h"
 
 #include "../audio.h"
 #include "../log.h"

M wl/text.c => wl/text.c +32 -6
@@ 13,14 13,14 @@ static FT_Face face = NULL;
 #define CURRENT_FACE_HEIGHT face->height / 64
 
 
-void draw_char(FT_Bitmap *bm, uint32_t x, uint32_t y)
+void draw_char_c(FT_Bitmap *bm, uint32_t x, uint32_t y, uint32_t c)
 {
     uint8_t *g = bm->buffer;
     uint32_t d;
     for (uint32_t i = 0; i < bm->rows; i++) {
         for (uint32_t j = 0; j < bm->width; j++) {
             if (*g) {
-                d = 0xff000000 | (*g) << 16 | (*g) << 8 | *g;
+                d = (0xff000000 | c) & ((*g) << 16 | (*g) << 8 | *g);
                 draw_pixel(x + j, y + i, d);
             }
             g++;


@@ 28,6 28,7 @@ void draw_char(FT_Bitmap *bm, uint32_t x, uint32_t y)
     }
 }
 
+
 void init_text(void)
 {
     FT_Init_FreeType(&library);


@@ 42,7 43,7 @@ void init_text(void)
 }
 
 
-void text_draw_string(const char *string, uint32_t x, uint32_t y)
+void text_string_c(const char *string, uint32_t x, uint32_t y, uint32_t c)
 {
     if (!string) {
         return;


@@ 56,14 57,14 @@ void text_draw_string(const char *string, uint32_t x, uint32_t y)
         FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
         FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
         if (x + face->glyph->bitmap_left + face->glyph->bitmap.width < WIDTH) {
-            draw_char(&face->glyph->bitmap, x + face->glyph->bitmap_left, y - face->glyph->bitmap_top);
+            draw_char_c(&face->glyph->bitmap, x + face->glyph->bitmap_left, y - face->glyph->bitmap_top, c);
         }
         x += face->glyph->advance.x >> 6;
     }
 }
 
 
-void text_draw_string_width(const char *string, uint32_t x, uint32_t y, uint32_t w)
+void text_string_width_c(const char *string, uint32_t x, uint32_t y, uint32_t w, uint32_t c)
 {
     if (!string) {
         return;


@@ 77,9 78,34 @@ void text_draw_string_width(const char *string, uint32_t x, uint32_t y, uint32_t
         FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL);
 
         if (x + face->glyph->bitmap_left + face->glyph->bitmap.width < w) {
-            draw_char(&face->glyph->bitmap, x + face->glyph->bitmap_left, y - face->glyph->bitmap_top);
+            draw_char_c(&face->glyph->bitmap, x + face->glyph->bitmap_left, y - face->glyph->bitmap_top, c);
         }
 
         x += face->glyph->advance.x >> 6;
     }
 }
+
+
+void text_string(const char *string, uint32_t x, uint32_t y)
+{
+    text_string_c(string, x, y, 0xffffffff);
+}
+
+
+void text_string_width(const char *string, uint32_t x, uint32_t y, uint32_t w)
+{
+    text_string_width_c(string, x, y, w, 0xffffffff);
+}
+
+
+void text_string_ralign(const char *string, uint32_t right, uint32_t y)
+{
+    // FIXME doesn't actually ralign :P
+    text_string_c(string, right, y, 0xffffffff);
+}
+
+void text_string_ralign_width(const char *string, uint32_t right, uint32_t y, uint32_t max_left)
+{
+    // FIXME doesn't actually ralign :P
+    text_string_width_c(string, right, y, max_left, 0xffffffff);
+}

M wl/text.h => wl/text.h +9 -2
@@ 7,8 7,15 @@ extern struct ui_panel nav_frame;
 
 void init_text(void);
 
-void text_draw_string(const char *string, uint32_t x, uint32_t y);
-void text_draw_string_width(const char *string, uint32_t x, uint32_t y, uint32_t w);
 
+void text_string_c(const char *string, uint32_t x, uint32_t y, uint32_t c);
+void text_string_width_c(const char *string, uint32_t x, uint32_t y, uint32_t w, uint32_t c);
+
+
+void text_string(const char *string, uint32_t x, uint32_t y);
+void text_string_width(const char *string, uint32_t x, uint32_t y, uint32_t w);
+
+void text_string_ralign(const char *string, uint32_t right, uint32_t y);
+void text_string_ralign_width(const char *string, uint32_t right, uint32_t y, uint32_t max_left);
 
 #endif // _HUDTDS_WL_TEXT_

M wl/touch.c => wl/touch.c +1 -1
@@ 1,8 1,8 @@
 #include "touch.h"
 
 #include "draw.h"
-#include "ui.h"
 
+#include "../ui.h"
 #include "../hud.h"
 #include "../wayland.h"
 #include "../log.h"