Browse Source

Add basic test of loading prefs conf file

master
cancel 5 years ago
parent
commit
d9ed4b401e
  1. 42
      sysmisc.c
  2. 3
      sysmisc.h
  3. 124
      tui_main.c

42
sysmisc.c

@ -1,5 +1,6 @@
#include "sysmisc.h" #include "sysmisc.h"
#include "gbuffer.h" #include "gbuffer.h"
#include "oso.h"
#include <ctype.h> #include <ctype.h>
ORCA_FORCE_NO_INLINE ORCA_FORCE_NO_INLINE
@ -168,3 +169,44 @@ ok:
*out_rightsize = b1 - b0; *out_rightsize = b1 - b0;
return Conf_read_left_and_right; return Conf_read_left_and_right;
} }
typedef enum {
Conf_dir_ok = 0,
Conf_dir_no_home,
} Conf_dir_error;
static char const* const xdg_config_home_env = "XDG_CONFIG_HOME";
static char const* const home_env = "HOME";
static char const* const conf_file_name = "/orca.conf";
static Conf_dir_error try_get_conf_dir(oso** out) {
char const* xdgcfgdir = getenv(xdg_config_home_env);
if (xdgcfgdir) {
Usz xdgcfgdirlen = strlen(xdgcfgdir);
if (xdgcfgdirlen > 0) {
osoputlen(out, xdgcfgdir, xdgcfgdirlen);
return Conf_dir_ok;
}
}
char const* homedir = getenv(home_env);
if (homedir) {
Usz homedirlen = strlen(homedir);
if (homedirlen > 0) {
osoputprintf(out, "%s/.config", homedir);
return Conf_dir_ok;
}
}
return Conf_dir_no_home;
}
FILE* conf_file_open_for_reading(void) {
oso* path = NULL;
if (try_get_conf_dir(&path))
return NULL;
osocat(&path, conf_file_name);
if (!path)
return NULL;
FILE* file = fopen(osoc(path), "r");
osofree(path);
return file;
}

3
sysmisc.h

@ -27,3 +27,6 @@ typedef enum {
Conf_read_result conf_read_line(FILE* file, char* buf, Usz bufsize, Conf_read_result conf_read_line(FILE* file, char* buf, Usz bufsize,
char** out_left, Usz* out_leftlen, char** out_left, Usz* out_leftlen,
char** out_right, Usz* out_rightlen); char** out_right, Usz* out_rightlen);
FILE* conf_file_open_for_reading(void);

124
tui_main.c

@ -10,6 +10,8 @@
#include <getopt.h> #include <getopt.h>
#include <locale.h> #include <locale.h>
#include <assert.h>
#define SOKOL_IMPL #define SOKOL_IMPL
#include "sokol_time.h" #include "sokol_time.h"
#undef SOKOL_IMPL #undef SOKOL_IMPL
@ -786,13 +788,40 @@ PmError portmidi_init_if_necessary(void) {
PmError midi_mode_init_portmidi(Midi_mode* mm, PmDeviceID dev_id) { PmError midi_mode_init_portmidi(Midi_mode* mm, PmDeviceID dev_id) {
PmError e = portmidi_init_if_necessary(); PmError e = portmidi_init_if_necessary();
if (e) if (e)
return e; goto fail;
e = Pm_OpenOutput(&mm->portmidi.stream, dev_id, NULL, 0, NULL, NULL, 0); e = Pm_OpenOutput(&mm->portmidi.stream, dev_id, NULL, 0, NULL, NULL, 0);
if (e) if (e)
return e; goto fail;
mm->portmidi.type = Midi_mode_type_portmidi; mm->portmidi.type = Midi_mode_type_portmidi;
mm->portmidi.device_id = dev_id; mm->portmidi.device_id = dev_id;
return pmNoError; return pmNoError;
fail:
midi_mode_init_null(mm);
return e;
}
// Returns true on success. todo currently output only
bool portmidi_find_device_id_by_name(char const* name, Usz namelen,
PmError* out_pmerror, PmDeviceID* out_id) {
fprintf(stderr, "hi there\n");
*out_pmerror = portmidi_init_if_necessary();
if (*out_pmerror)
return false;
int num = Pm_CountDevices();
for (int i = 0; i < num; ++i) {
PmDeviceInfo const* info = Pm_GetDeviceInfo(i);
if (!info || !info->output)
continue;
Usz len = strlen(info->name);
fprintf(stderr, "trying: %s\n", info->name);
if (len != namelen)
continue;
if (strncmp(name, info->name, namelen) == 0) {
*out_id = i;
return true;
}
}
return false;
} }
#endif #endif
void midi_mode_deinit(Midi_mode* mm) { void midi_mode_deinit(Midi_mode* mm) {
@ -2340,6 +2369,64 @@ char const* field_load_error_string(Field_load_error fle) {
return errstr; return errstr;
} }
typedef struct {
oso* portmidi_output_device;
} Prefs;
void prefs_init(Prefs* p) { memset(p, 0, sizeof(Prefs)); }
void prefs_deinit(Prefs* p) { osofree(p->portmidi_output_device); }
typedef enum {
Prefs_load_ok = 0,
} Prefs_load_error;
ORCA_FORCE_NO_INLINE
Prefs_load_error prefs_load_from_conf_file(Prefs* p) {
(void)p;
FILE* conffile = conf_file_open_for_reading();
if (!conffile) {
return Prefs_load_ok;
}
char linebuff[512];
for (;;) {
char *left, *right;
Usz leftsz, rightsz;
Conf_read_result res = conf_read_line(conffile, linebuff, sizeof linebuff,
&left, &leftsz, &right, &rightsz);
switch (res) {
case Conf_read_left_and_right: {
if (strcmp("portmidi_output_device", left) == 0) {
osoput(&p->portmidi_output_device, right);
}
continue;
}
case Conf_read_irrelevant:
continue;
case Conf_read_buffer_too_small:
case Conf_read_eof:
case Conf_read_io_error:
break;
}
break;
}
fclose(conffile);
return Prefs_load_ok;
}
void print_loading_message(char const* s) {
Usz len = strlen(s);
if (len > INT_MAX)
return;
int h, w;
getmaxyx(stdscr, h, w);
int y = h / 2;
int x = (int)len < w ? (w - (int)len) / 2 : 0;
werase(stdscr);
wmove(stdscr, y, x);
waddstr(stdscr, s);
refresh();
}
// //
// main // main
// //
@ -2582,6 +2669,8 @@ int main(int argc, char** argv) {
osofree(file_name); osofree(file_name);
exit(1); exit(1);
} }
mbuf_reusable_ensure_size(&ged_state.mbuf_r, ged_state.field.height,
ged_state.field.width);
} else { } else {
// Temp hacky stuff: we've crammed two code paths into the KEY_RESIZE event // Temp hacky stuff: we've crammed two code paths into the KEY_RESIZE event
// case. One of them is for the initial setup for an automatic grid size. // case. One of them is for the initial setup for an automatic grid size.
@ -2595,6 +2684,8 @@ int main(int argc, char** argv) {
if (!should_autosize_grid) { if (!should_autosize_grid) {
field_init_fill(&ged_state.field, (Usz)init_grid_dim_y, field_init_fill(&ged_state.field, (Usz)init_grid_dim_y,
(Usz)init_grid_dim_x, '.'); (Usz)init_grid_dim_x, '.');
mbuf_reusable_ensure_size(&ged_state.mbuf_r, ged_state.field.height,
ged_state.field.width);
} }
} }
ged_state.filename = osolen(file_name) ? osoc(file_name) : "unnamed"; ged_state.filename = osolen(file_name) ? osoc(file_name) : "unnamed";
@ -2641,6 +2732,34 @@ int main(int argc, char** argv) {
printf("\033[?2004h\n"); // Ask terminal to use bracketed paste. printf("\033[?2004h\n"); // Ask terminal to use bracketed paste.
Prefs prefs;
prefs_init(&prefs);
Prefs_load_error prefserr = prefs_load_from_conf_file(&prefs);
if (prefserr == Prefs_load_ok) {
#ifdef FEAT_PORTMIDI
if (osolen(prefs.portmidi_output_device)) {
// PortMidi can be hilariously slow to initialize. Since it will be
// initialized automatically if the user has a prefs entry for PortMidi
// devices, we should show a message to the user letting them know why
// orca is locked up/frozen. (When it's done via menu action, that's
// fine, since they can figure out why.)
print_loading_message("Waiting on PortMidi...");
PmError pmerr;
PmDeviceID devid;
if (portmidi_find_device_id_by_name(osoc(prefs.portmidi_output_device),
osolen(prefs.portmidi_output_device),
&pmerr, &devid)) {
midi_mode_deinit(&midi_mode);
pmerr = midi_mode_init_portmidi(&midi_mode, devid);
if (pmerr) {
// todo stuff
}
}
}
#endif
}
prefs_deinit(&prefs);
WINDOW* cont_window = NULL; WINDOW* cont_window = NULL;
int key = KEY_RESIZE; int key = KEY_RESIZE;
@ -2995,6 +3114,7 @@ int main(int argc, char** argv) {
} break; } break;
#ifdef FEAT_PORTMIDI #ifdef FEAT_PORTMIDI
case Portmidi_output_device_menu_id: { case Portmidi_output_device_menu_id: {
ged_stop_all_sustained_notes(&ged_state);
midi_mode_deinit(&midi_mode); midi_mode_deinit(&midi_mode);
PmError pme = midi_mode_init_portmidi(&midi_mode, act.picked.id); PmError pme = midi_mode_init_portmidi(&midi_mode, act.picked.id);
qnav_stack_pop(); qnav_stack_pop();

Loading…
Cancel
Save