mirror of https://git.mastrix.org/lda/Mastrix
[ADD/WIP] Actually make the login screen "usable"
It now actually does a login request, and notifies you of the status. I'll still need to make sure that it stores the user somewhere...
This commit is contained in:
parent
dad4a844a6
commit
3612d306af
|
@ -5,7 +5,10 @@
|
|||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#define INITIAL_CAPACITY 10
|
||||
#include <gint/keyboard.h>
|
||||
#include <gint/display.h>
|
||||
|
||||
#define INITIAL_CAPACITY 11
|
||||
|
||||
typedef struct hm_bucket {
|
||||
bool used;
|
||||
|
@ -26,12 +29,12 @@ struct hashmap {
|
|||
static size_t string_hash(char *str)
|
||||
{
|
||||
size_t length = strlen(str);
|
||||
size_t hash = 0;
|
||||
size_t hash = 5381;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < strlen(str); i++)
|
||||
{
|
||||
hash = (5 * (hash + str[i])) ^ i; /* shitty hashing algo */
|
||||
hash = (hash << 5) + hash + str[i];
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
@ -61,6 +64,8 @@ void utils_hashmap_add(hashmap_t *hm, char *key, void *val)
|
|||
|
||||
bool found = false;
|
||||
|
||||
size_t i;
|
||||
|
||||
if (!hm || !key || !val)
|
||||
{
|
||||
return;
|
||||
|
@ -84,11 +89,17 @@ void utils_hashmap_add(hashmap_t *hm, char *key, void *val)
|
|||
if (found) return;
|
||||
|
||||
hm->buckets = reallocarray(
|
||||
hm->buckets, ++hm->capacity, sizeof(hm_bucket_t)
|
||||
hm->buckets, hm->capacity + INITIAL_CAPACITY, sizeof(hm_bucket_t)
|
||||
);
|
||||
hm->buckets[hm->capacity - 1].used = true;
|
||||
hm->buckets[hm->capacity - 1].string = utils_strcpy(key);
|
||||
hm->buckets[hm->capacity - 1].value = val;
|
||||
for (i = 0; i < INITIAL_CAPACITY; i++)
|
||||
{
|
||||
hm->buckets[i + hm->capacity].used = false;
|
||||
}
|
||||
|
||||
hm->buckets[hm->capacity].used = true;
|
||||
hm->buckets[hm->capacity].string = utils_strcpy(key);
|
||||
hm->buckets[hm->capacity].value = val;
|
||||
hm->capacity += INITIAL_CAPACITY;
|
||||
}
|
||||
|
||||
void * utils_hashmap_get(hashmap_t *hm, char *key)
|
||||
|
@ -105,6 +116,13 @@ void * utils_hashmap_get(hashmap_t *hm, char *key)
|
|||
|
||||
hash = string_hash(key);
|
||||
lhsh = hash % hm->capacity;
|
||||
if (!strcmp(key, "login"))
|
||||
{
|
||||
dclear(C_RED);
|
||||
dprint(1, 1, C_WHITE, "Hash: %d", lhsh);
|
||||
dupdate();
|
||||
getkey();
|
||||
}
|
||||
for (probing = 0; probing < (lhsh); probing++)
|
||||
{
|
||||
size_t idx = (lhsh + probing) % hm->capacity;
|
||||
|
@ -117,6 +135,62 @@ void * utils_hashmap_get(hashmap_t *hm, char *key)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
void * utils_hashmap_set(hashmap_t *hm, char *key, void *value)
|
||||
{
|
||||
size_t hash, probing;
|
||||
size_t lhsh;
|
||||
|
||||
bool found = false;
|
||||
|
||||
void *prev = NULL;
|
||||
|
||||
size_t i;
|
||||
|
||||
if (!hm || !key || !value)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
hash = string_hash(key);
|
||||
lhsh = hash % hm->capacity;
|
||||
if (!strcmp(key, "login"))
|
||||
{
|
||||
dclear(C_RED);
|
||||
dprint(1, 1, C_WHITE, "Hash: %d", lhsh);
|
||||
dupdate();
|
||||
getkey();
|
||||
}
|
||||
for (probing = 0; probing < (lhsh); probing++)
|
||||
{
|
||||
size_t idx = (lhsh + probing) % hm->capacity;
|
||||
if (hm->buckets[idx].used && !strcmp(key, hm->buckets[idx].string))
|
||||
{
|
||||
free(hm->buckets[idx].string);
|
||||
prev = hm->buckets[idx].value;
|
||||
|
||||
found = true;
|
||||
hm->buckets[idx].string = utils_strcpy(key);
|
||||
hm->buckets[idx].value = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) return prev;
|
||||
|
||||
hm->buckets = reallocarray(
|
||||
hm->buckets, hm->capacity + INITIAL_CAPACITY, sizeof(hm_bucket_t)
|
||||
);
|
||||
for (i = 0; i < INITIAL_CAPACITY; i++)
|
||||
{
|
||||
hm->buckets[i + hm->capacity].used = false;
|
||||
}
|
||||
|
||||
hm->buckets[hm->capacity].used = true;
|
||||
hm->buckets[hm->capacity].string = utils_strcpy(key);
|
||||
hm->buckets[hm->capacity].value = value;
|
||||
hm->capacity += INITIAL_CAPACITY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void * utils_hashmap_del(hashmap_t *hm, char *key)
|
||||
{
|
||||
|
|
|
@ -90,6 +90,7 @@ void http_transfer_set_data(http_transfer_t *t, void *data, size_t len)
|
|||
}
|
||||
|
||||
t->request = malloc(len);
|
||||
t->req_length = len;
|
||||
memcpy(t->request, data, len);
|
||||
}
|
||||
|
||||
|
@ -145,6 +146,13 @@ void http_transfer_send(http_transfer_t *t)
|
|||
add_header("\r\n");
|
||||
|
||||
free(line);
|
||||
if (t->request)
|
||||
{
|
||||
len_line = snprintf(NULL, 0, "%ld", t->req_length);
|
||||
line = malloc(len_line + 1);
|
||||
snprintf(line, len_line + 1, "%ld", t->req_length);
|
||||
utils_hashmap_add(t->req_header, "Content-Length", line);
|
||||
}
|
||||
|
||||
while (utils_hashmap_list(t->req_header, &key, (void **) &val))
|
||||
{
|
||||
|
@ -157,7 +165,6 @@ void http_transfer_send(http_transfer_t *t)
|
|||
}
|
||||
add_header("\r\n");
|
||||
|
||||
|
||||
len = strlen(header);
|
||||
if (t->request)
|
||||
{
|
||||
|
|
|
@ -32,13 +32,13 @@ typedef struct ui_session {
|
|||
|
||||
struct ui_screen;
|
||||
typedef void * (*screen_setup_t)(struct ui_screen *that);
|
||||
typedef void (*screen_focus_t)(struct ui_screen *that);
|
||||
typedef void (*screen_event_t)(struct ui_screen *that, jevent event);
|
||||
typedef void * (*screen_focus_t)(struct ui_screen *that);
|
||||
typedef void * (*screen_event_t)(struct ui_screen *that, jevent event);
|
||||
|
||||
typedef struct ui_screen {
|
||||
ui_session_t *owner;
|
||||
void *widget;
|
||||
hashmap_t *data; /* Personal data within screen */
|
||||
void *data;
|
||||
|
||||
screen_setup_t init;
|
||||
screen_focus_t on_focus;
|
||||
|
|
|
@ -8,6 +8,6 @@
|
|||
extern void * ui_infos_init(ui_screen_t *that);
|
||||
|
||||
extern void * ui_login_init(ui_screen_t *that);
|
||||
extern void ui_login_focus(ui_screen_t *that);
|
||||
extern void ui_login_event(ui_screen_t *that, jevent e);
|
||||
extern void * ui_login_focus(ui_screen_t *that);
|
||||
extern void * ui_login_event(ui_screen_t *that, jevent e);
|
||||
#endif
|
||||
|
|
|
@ -14,6 +14,7 @@ typedef struct hashmap hashmap_t;
|
|||
extern hashmap_t * utils_new_hashmap(void);
|
||||
extern void utils_hashmap_add(hashmap_t *, char *, void *);
|
||||
extern void * utils_hashmap_get(hashmap_t *, char *);
|
||||
extern void * utils_hashmap_set(hashmap_t *, char *, void *);
|
||||
extern void * utils_hashmap_del(hashmap_t *, char *);
|
||||
extern bool utils_hashmap_list(hashmap_t *, char **, void **);
|
||||
extern void utils_free_hashmap(hashmap_t *);
|
||||
|
|
18
src/login.c
18
src/login.c
|
@ -1,5 +1,8 @@
|
|||
#include <matrix.h>
|
||||
|
||||
#include <gint/display.h>
|
||||
#include <gint/keyboard.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
@ -86,6 +89,10 @@ m_user_t *matrix_login(char *server, char *user, char *password)
|
|||
request,
|
||||
"type", utils_string_as_json(utils_strcpy("m.login.password"))
|
||||
);
|
||||
utils_hashmap_add(
|
||||
request,
|
||||
"password", utils_string_as_json(utils_strcpy(password))
|
||||
);
|
||||
utils_hashmap_add(
|
||||
request,
|
||||
"initial_device_display_name",
|
||||
|
@ -110,18 +117,27 @@ m_user_t *matrix_login(char *server, char *user, char *password)
|
|||
data = utils_json_write(request, &data_len);
|
||||
utils_free_json(request);
|
||||
|
||||
data_len = strlen(data);
|
||||
|
||||
|
||||
trans = http_transfer_create(
|
||||
HTTP_POST, server, "/_matrix/client/v3/login"
|
||||
);
|
||||
|
||||
http_transfer_add_header(trans, "User-Agent", "Mastrix/1.0 (fx-CG50)");
|
||||
http_transfer_set_data(trans, data, data_len);
|
||||
http_transfer_set_data(trans, data, strlen(data));
|
||||
http_transfer_send(trans);
|
||||
free(data);
|
||||
|
||||
if (http_transfer_code(trans) != 200)
|
||||
{
|
||||
char *msg = http_get_reply_data(trans, &data_len);
|
||||
ret = NULL;
|
||||
dclear(C_RED);
|
||||
dprint(1, 1, C_WHITE, "Code %d", http_transfer_code(trans));
|
||||
dprint(1, 11, C_WHITE, "%.*s", data_len, msg);
|
||||
dupdate();
|
||||
getkey();
|
||||
goto end;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,7 @@ int main(void)
|
|||
int in, out;
|
||||
usb_fxlink_header_t reply;
|
||||
|
||||
/*easter_goda();
|
||||
getkey();*/
|
||||
getkey();
|
||||
|
||||
dclear(C_WHITE);
|
||||
dtext(1, 1, C_BLACK, "Waiting for USB link...");
|
||||
|
|
35
src/ui.c
35
src/ui.c
|
@ -37,17 +37,18 @@ ui_session_t *ui_create_session(void)
|
|||
}
|
||||
size_t ui_add_screen(ui_session_t *ui, ui_screen_t *screen)
|
||||
{
|
||||
size_t ret;
|
||||
if (!ui || !screen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
screen->owner = ui;
|
||||
screen->data = utils_new_hashmap();
|
||||
|
||||
screen->widget = screen->init(screen);
|
||||
|
||||
ui_set_screen(ui, utils_array_add(ui->screens, screen));
|
||||
ui_set_screen(ui, (ret = utils_array_add(ui->screens, screen)));
|
||||
return ret;
|
||||
}
|
||||
ui_screen_t * ui_set_screen(ui_session_t *ui, size_t idx)
|
||||
{
|
||||
|
@ -68,30 +69,41 @@ ui_screen_t * ui_set_screen(ui_session_t *ui, size_t idx)
|
|||
jscene_show_and_focus(ui->justui_screen, indexed->widget);
|
||||
if (indexed->on_focus)
|
||||
{
|
||||
indexed->on_focus(indexed);
|
||||
void *widget = indexed->on_focus(indexed);
|
||||
if (widget)
|
||||
{
|
||||
jscene_set_focused_widget(ui->justui_screen, widget);
|
||||
}
|
||||
}
|
||||
|
||||
return indexed;
|
||||
}
|
||||
static void ui_manage_event(ui_session_t *ui, jevent e)
|
||||
static bool ui_manage_event(ui_session_t *ui, jevent e)
|
||||
{
|
||||
ui_screen_t *screen;
|
||||
void *widget;
|
||||
if (!ui)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (ui->current_screen == -1)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
screen = utils_array_get(ui->screens, ui->current_screen);
|
||||
|
||||
if (!screen || !screen->on_event)
|
||||
{
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
screen->on_event(screen, e);
|
||||
widget = screen->on_event(screen, e);
|
||||
if (widget)
|
||||
{
|
||||
jscene_set_focused_widget(ui->justui_screen, widget);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ui_session_loop(ui_session_t *ui)
|
||||
{
|
||||
|
@ -107,7 +119,12 @@ void ui_session_loop(ui_session_t *ui)
|
|||
dupdate();
|
||||
continue;
|
||||
}
|
||||
ui_manage_event(ui, e);
|
||||
if (ui_manage_event(ui, e))
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
jscene_render(ui->justui_screen);
|
||||
dupdate();
|
||||
}
|
||||
key = e.key.key;
|
||||
}
|
||||
}
|
||||
|
|
138
src/ui_login.c
138
src/ui_login.c
|
@ -15,6 +15,14 @@
|
|||
|
||||
extern const bopti_image_t mastrix;
|
||||
|
||||
typedef struct login_data {
|
||||
jinput *server, *login, *password;
|
||||
void *focusing;
|
||||
jlabel *error;
|
||||
|
||||
char *delegated;
|
||||
} login_data_t;
|
||||
|
||||
void draw_mastrix(int x, int y)
|
||||
{
|
||||
dimage(x, y, &mastrix);
|
||||
|
@ -29,9 +37,13 @@ void * ui_login_init(ui_screen_t *that)
|
|||
jlabel *login_to_mastrix = jlabel_create(
|
||||
"Login to Matrix", login_widget
|
||||
);
|
||||
login_data_t *data;
|
||||
jlabel *error;
|
||||
jpainted *logo;
|
||||
login_content = jwidget_create(login_widget);
|
||||
that->data = malloc(sizeof(login_data_t));
|
||||
data = that->data;
|
||||
data->delegated = NULL;
|
||||
|
||||
jlayout_set_vbox(login_widget)->spacing = 3;
|
||||
jwidget_set_padding(login_widget, 0, 0, 0, 0);
|
||||
|
@ -75,45 +87,34 @@ void * ui_login_init(ui_screen_t *that)
|
|||
jwidget_set_stretch(password, 1, 0, true);
|
||||
|
||||
/* Store those so that they can be referenced later */
|
||||
utils_hashmap_add(that->data, "server", server);
|
||||
utils_hashmap_add(that->data, "login", login);
|
||||
utils_hashmap_add(that->data, "password", password);
|
||||
utils_hashmap_add(that->data, "error", error);
|
||||
|
||||
utils_hashmap_add(that->data, "focusing", "server");
|
||||
data->server = server;
|
||||
data->login = login;
|
||||
data->password = password;
|
||||
data->focusing = server;
|
||||
data->error = error;
|
||||
|
||||
|
||||
return login_widget;
|
||||
}
|
||||
void ui_login_focus(ui_screen_t *that)
|
||||
void * ui_login_focus(ui_screen_t *that)
|
||||
{
|
||||
char *focus_to = utils_hashmap_get(that->data, "focusing");
|
||||
|
||||
if (!strcmp(focus_to, "server"))
|
||||
{
|
||||
void *server = utils_hashmap_get(that->data, "server");
|
||||
jscene_show_and_focus(that->owner->justui_screen, server);
|
||||
}
|
||||
else if (!strcmp(focus_to, "login"))
|
||||
{
|
||||
void *login = utils_hashmap_get(that->data, "login");
|
||||
jscene_show_and_focus(that->owner->justui_screen, login);
|
||||
}
|
||||
else if (!strcmp(focus_to, "password"))
|
||||
{
|
||||
void *password = utils_hashmap_get(that->data, "password");
|
||||
jscene_show_and_focus(that->owner->justui_screen, password);
|
||||
}
|
||||
login_data_t *data = that->data;
|
||||
return data->focusing;
|
||||
}
|
||||
void ui_login_event(ui_screen_t *that, jevent e)
|
||||
void * ui_login_event(ui_screen_t *that, jevent e)
|
||||
{
|
||||
char *focus_to = utils_hashmap_get(that->data, "focusing");
|
||||
login_data_t *data = that->data;
|
||||
|
||||
if (e.type == JINPUT_VALIDATED)
|
||||
{
|
||||
if (!strcmp(focus_to, "server"))
|
||||
jinput *server, *login, *password;
|
||||
jlabel *error = data->error;
|
||||
|
||||
server = data->server;
|
||||
login = data->login;
|
||||
password = data->password;
|
||||
if (data->focusing == data->server)
|
||||
{
|
||||
jinput *server = utils_hashmap_get(that->data, "server");
|
||||
char *delegated = NULL;
|
||||
char *serv_name = (char *) jinput_value(server);
|
||||
m_delegation_t status;
|
||||
|
@ -129,52 +130,89 @@ void ui_login_event(ui_screen_t *that, jevent e)
|
|||
{
|
||||
case DELEG_FAIL_ERROR:
|
||||
jlabel_asprintf(
|
||||
utils_hashmap_get(that->data, "error"),
|
||||
error,
|
||||
"Couldn't find a correct servname for '%s'.",
|
||||
serv_name
|
||||
);
|
||||
jlabel_set_text_color(
|
||||
utils_hashmap_get(that->data, "error"),
|
||||
C_RED
|
||||
);
|
||||
jlabel_set_text_color(error, C_RED);
|
||||
break;
|
||||
case DELEG_IGNORE:
|
||||
delegated = utils_strcpy(serv_name);
|
||||
break;
|
||||
case DELEG_SUCCESS:
|
||||
jlabel_asprintf(
|
||||
utils_hashmap_get(that->data, "error"),
|
||||
error,
|
||||
"'%s' => '%s'",
|
||||
serv_name, delegated
|
||||
);
|
||||
jlabel_set_text_color(
|
||||
utils_hashmap_get(that->data, "error"),
|
||||
C_GREEN
|
||||
);
|
||||
jlabel_set_text_color(error, C_GREEN);
|
||||
break;
|
||||
case DELEG_FAIL_PROMPT:
|
||||
jlabel_set_text_color(error, C_RED);
|
||||
case DELEG_PROMPT:
|
||||
jlabel_asprintf(
|
||||
utils_hashmap_get(that->data, "error"),
|
||||
error,
|
||||
"Please enter the delegation for '%s'.",
|
||||
serv_name
|
||||
);
|
||||
jlabel_set_text_color(
|
||||
utils_hashmap_get(that->data, "error"),
|
||||
C_BLACK
|
||||
);
|
||||
break;
|
||||
}
|
||||
if (delegated)
|
||||
{
|
||||
char *copy = utils_hashmap_get(that->data, "delegated");
|
||||
if (copy)
|
||||
{
|
||||
free(copy);
|
||||
}
|
||||
utils_hashmap_add(that->data, "delegated", delegated);
|
||||
if (data->delegated) free(data->delegated);
|
||||
data->delegated = delegated;
|
||||
|
||||
data->focusing = data->login;
|
||||
return ui_login_focus(that);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
else if (data->focusing == data->login)
|
||||
{
|
||||
char *username = (char *) jinput_value(data->login);
|
||||
if (!strcmp(username, ""))
|
||||
{
|
||||
jlabel_set_text_color(error, C_RED);
|
||||
jlabel_asprintf(error, "Empty usernames are not allowed.");
|
||||
return NULL;
|
||||
}
|
||||
data->focusing = data->password;
|
||||
return ui_login_focus(that);
|
||||
}
|
||||
else if (data->focusing == data->password)
|
||||
{
|
||||
char *username = (char *) jinput_value(data->login);
|
||||
char *password = (char *) jinput_value(data->password);
|
||||
|
||||
m_user_t *user;
|
||||
if (!strcmp(password, ""))
|
||||
{
|
||||
jlabel_set_text_color(error, C_RED);
|
||||
jlabel_asprintf(error, "Empty password are not allowed.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return;
|
||||
/* Submit the login process out... */
|
||||
jlabel_set_text_color(error, C_BLACK);
|
||||
jlabel_asprintf(error, "Logging in...");
|
||||
|
||||
user = matrix_login(data->delegated, username, password);
|
||||
if (user)
|
||||
{
|
||||
jlabel_set_text_color(error, C_GREEN);
|
||||
jlabel_asprintf(error, "Logged in (DID: %s)!", user->device_id);
|
||||
|
||||
/* TODO: Store user data *somewhere* */
|
||||
|
||||
return NULL; /* TODO: Change screen, since we're logged in */
|
||||
}
|
||||
else
|
||||
{
|
||||
jlabel_set_text_color(error, C_RED);
|
||||
jlabel_asprintf(error, "Couldn't login as '%s'", username);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue