06b97952836245dce43bba4ccd85ef32ca0b77db — Gregory Mullen 5 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 = 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-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 @@ 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 @@ 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 @@       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 @@ .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 @@ .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 @@ .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 @@       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 @@ .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 @@ }
          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 @@ .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 @@ 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 @@ 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 @@ 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 @@ 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 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 @@ (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_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 @@ (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_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 @@ (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 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_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_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_3 = {
      .name = "music_btn_3",
      .color = 0xffff00ff,
+     .enabled = true,
      .draw = draw_button,
      .t_dn = music_btn_tracks,
      .pos_x = 0,


@@ 204,10 247,11 @@ 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 @@ 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_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_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_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_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_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_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 @@ 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 @@ #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_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_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_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_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_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 @@ (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 @@   
  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_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 @@ 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 @@ .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 @@ 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 @@ (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 @@ 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 @@ }
  
  
- 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 @@ .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 @@ 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 @@ if (children) {
          struct ui_panel *p;
          while ((p = *children++)) {
-             if (p->disabled) {
+             if (!p->enabled) {
                  continue;
              }
  


@@ 69,7 69,7 @@ if (children) {
          struct ui_panel *p;
          while ((p = *children++)) {
-             if (p->disabled) {
+             if (!p->enabled) {
                  continue;
              }
  


@@ 179,9 179,10 @@ 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 @@ PANEL_LIST,
      PANEL_LIST_ENTRY,
  
- 
      PANEL_OTHER,
      PANEL_MAX = 255
  } PANEL_TYPE;


@@ 49,7 48,7 @@       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 @@ 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 @@ 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 @@ 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 @@ }  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 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 @@ 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 @@ 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 @@ #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 init_text(void)
  {
      FT_Init_FreeType(&library);


@@ 42,7 43,7 @@ }
  
  
- 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 @@ 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 @@ 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 @@   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"