Various improvements to glogin
This commit is contained in:
parent
8a1430879a
commit
338174a75c
@ -26,8 +26,9 @@
|
||||
#include "lib/yutani.h"
|
||||
#include "lib/toaru_auth.h"
|
||||
|
||||
sprite_t * sprites[128];
|
||||
sprite_t alpha_tmp;
|
||||
#include "gui/ttk/ttk.h"
|
||||
|
||||
sprite_t logo;
|
||||
|
||||
gfx_context_t * ctx;
|
||||
|
||||
@ -37,6 +38,13 @@ uint16_t win_height;
|
||||
int uid = 0;
|
||||
|
||||
#define LOGO_FINAL_OFFSET 100
|
||||
#define BOX_WIDTH 272
|
||||
#define BOX_HEIGHT 104
|
||||
#define USERNAME_BOX 1
|
||||
#define PASSWORD_BOX 2
|
||||
#define EXTRA_TEXT_OFFSET 15
|
||||
#define TEXTBOX_INTERIOR_LEFT 4
|
||||
#define LEFT_OFFSET 84
|
||||
|
||||
int center_x(int x) {
|
||||
return (win_width - x) / 2;
|
||||
@ -46,11 +54,6 @@ int center_y(int y) {
|
||||
return (win_height - y) / 2;
|
||||
}
|
||||
|
||||
void init_sprite_png(int id, char * path) {
|
||||
sprites[id] = malloc(sizeof(sprite_t));
|
||||
load_sprite_png(sprites[id], path);
|
||||
}
|
||||
|
||||
#define INPUT_SIZE 1024
|
||||
int buffer_put(char * input_buffer, char c) {
|
||||
int input_collected = strlen(input_buffer);
|
||||
@ -74,11 +77,6 @@ int buffer_put(char * input_buffer, char c) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void * process_input(void * arg) {
|
||||
while (1) {
|
||||
}
|
||||
}
|
||||
|
||||
int32_t min(int32_t a, int32_t b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
@ -110,23 +108,125 @@ void draw_box_border(gfx_context_t * ctx, int32_t x, int32_t y, int32_t w, int32
|
||||
draw_line(ctx, _max_x, _max_x, _min_y, _max_y, color);
|
||||
}
|
||||
|
||||
int main (int argc, char ** argv) {
|
||||
init_sprite_png(0, "/usr/share/logo_login.png");
|
||||
init_sprite_png(1, "/usr/share/wallpaper.png");
|
||||
init_shmemfonts();
|
||||
struct text_box {
|
||||
int x;
|
||||
int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
fprintf(stderr, "glogin here, hello world.\n");
|
||||
uint32_t text_color;
|
||||
|
||||
struct login_container * parent;
|
||||
|
||||
int is_focused:1;
|
||||
int is_password:1;
|
||||
|
||||
unsigned int cursor;
|
||||
char * buffer;
|
||||
|
||||
char * placeholder;
|
||||
};
|
||||
|
||||
struct login_container {
|
||||
int x;
|
||||
int y;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
|
||||
struct text_box * username_box;
|
||||
struct text_box * password_box;
|
||||
|
||||
int show_error:1;
|
||||
};
|
||||
|
||||
void draw_text_box(cairo_t * cr, struct text_box * tb) {
|
||||
int x = tb->parent->x + tb->x;
|
||||
int y = tb->parent->y + tb->y;
|
||||
|
||||
set_font_size(13);
|
||||
int text_offset = 15;
|
||||
|
||||
cairo_rounded_rectangle(cr, 1 + x, 1 + y, tb->width - 2, tb->height - 2, 2.0);
|
||||
if (tb->is_focused) {
|
||||
cairo_set_source_rgba(cr, 8.0/255.0, 193.0/255.0, 236.0/255.0, 1.0);
|
||||
} else {
|
||||
cairo_set_source_rgba(cr, 158.0/255.0, 169.0/255.0, 177.0/255.0, 1.0);
|
||||
}
|
||||
cairo_set_line_width(cr, 2);
|
||||
cairo_stroke(cr);
|
||||
|
||||
{
|
||||
cairo_pattern_t * pat = cairo_pattern_create_linear(1 + x, 1 + y, 1 + x, 1 + y + tb->height - 2);
|
||||
if (tb->is_focused) {
|
||||
cairo_pattern_add_color_stop_rgba(pat, 0, 241.0/255.0, 241.0/255.0, 244.0/255.0, 1.0);
|
||||
cairo_pattern_add_color_stop_rgba(pat, 1, 1, 1, 1, 1.0);
|
||||
} else {
|
||||
cairo_pattern_add_color_stop_rgba(pat, 0, 241.0/255.0, 241.0/255.0, 244.0/255.0, 0.9);
|
||||
cairo_pattern_add_color_stop_rgba(pat, 1, 1, 1, 1, 0.9);
|
||||
}
|
||||
cairo_rounded_rectangle(cr, 1 + x, 1 + y, tb->width - 2, tb->height - 2, 2.0);
|
||||
cairo_set_source(cr, pat);
|
||||
cairo_fill(cr);
|
||||
cairo_pattern_destroy(pat);
|
||||
}
|
||||
|
||||
char * text = tb->buffer;
|
||||
char password_circles[512];
|
||||
uint32_t color = tb->text_color;
|
||||
|
||||
if (strlen(tb->buffer) == 0 && !tb->is_focused) {
|
||||
text = tb->placeholder;
|
||||
color = rgba(0,0,0,127);
|
||||
} else if (tb->is_password) {
|
||||
strcpy(password_circles, "");
|
||||
for (int i = 0; i < strlen(tb->buffer); ++i) {
|
||||
strcat(password_circles, "⚫");
|
||||
}
|
||||
text = password_circles;
|
||||
}
|
||||
|
||||
draw_string(ctx, x + TEXTBOX_INTERIOR_LEFT, y + text_offset, color, text);
|
||||
|
||||
if (tb->is_focused) {
|
||||
int width = draw_string_width(text);
|
||||
draw_line(ctx, x + TEXTBOX_INTERIOR_LEFT + width, x + TEXTBOX_INTERIOR_LEFT + width, y + 2, y + text_offset + 1, tb->text_color);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void draw_login_container(cairo_t * cr, struct login_container * lc) {
|
||||
|
||||
/* Draw rounded rectangle */
|
||||
cairo_rounded_rectangle(cr, lc->x, lc->y, lc->width, lc->height, 4.0);
|
||||
cairo_set_source_rgba(cr, 0.0, 0.0, 0.0, 0.75);
|
||||
cairo_fill(cr);
|
||||
|
||||
/* Draw labels */
|
||||
if (lc->show_error) {
|
||||
char * error_message = "Incorrect username or password.";
|
||||
|
||||
set_font_size(11);
|
||||
draw_string(ctx, lc->x + (lc->width - draw_string_width(error_message)) / 2, lc->y + 6 + EXTRA_TEXT_OFFSET, rgb(240, 20, 20), error_message);
|
||||
}
|
||||
|
||||
draw_text_box(cr, lc->username_box);
|
||||
draw_text_box(cr, lc->password_box);
|
||||
|
||||
}
|
||||
|
||||
int main (int argc, char ** argv) {
|
||||
load_sprite_png(&logo, "/usr/share/logo_login.png");
|
||||
init_shmemfonts();
|
||||
|
||||
yutani_t * y = yutani_init();
|
||||
|
||||
if (!y) {
|
||||
fprintf(stderr, "[demo-client] Connection to server failed.\n");
|
||||
fprintf(stderr, "[glogin] Connection to server failed.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Generate surface for background */
|
||||
sprite_t * bg_sprite;
|
||||
cairo_surface_t * bg_surf;
|
||||
|
||||
int width = y->display_width;
|
||||
int height = y->display_height;
|
||||
@ -139,23 +239,29 @@ int main (int argc, char ** argv) {
|
||||
assert(wina);
|
||||
yutani_set_stack(y, wina, 0);
|
||||
ctx = init_graphics_yutani_double_buffer(wina);
|
||||
draw_fill(ctx, rgba(0,0,0,0));
|
||||
draw_fill(ctx, rgba(0,0,0,255));
|
||||
yutani_flip(y, wina);
|
||||
|
||||
{
|
||||
float x = (float)width / (float)sprites[1]->width;
|
||||
float y = (float)height / (float)sprites[1]->height;
|
||||
cairo_surface_t * cs = cairo_image_surface_create_for_data((void*)ctx->backbuffer, CAIRO_FORMAT_ARGB32, ctx->width, ctx->height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, ctx->width));
|
||||
cairo_t * cr = cairo_create(cs);
|
||||
|
||||
int nh = (int)(x * (float)sprites[1]->height);
|
||||
int nw = (int)(y * (float)sprites[1]->width);;
|
||||
{
|
||||
sprite_t * wallpaper = malloc(sizeof(sprite_t));
|
||||
load_sprite_png(wallpaper, "/usr/share/wallpaper.png");
|
||||
|
||||
float x = (float)width / (float)wallpaper->width;
|
||||
float y = (float)height / (float)wallpaper->height;
|
||||
|
||||
int nh = (int)(x * (float)wallpaper->height);
|
||||
int nw = (int)(y * (float)wallpaper->width);;
|
||||
|
||||
bg_sprite = create_sprite(width, height, ALPHA_OPAQUE);
|
||||
gfx_context_t * bg = init_graphics_sprite(bg_sprite);
|
||||
|
||||
if (nw > width) {
|
||||
draw_sprite_scaled(bg, sprites[1], (width - nw) / 2, 0, nw, height);
|
||||
draw_sprite_scaled(bg, wallpaper, (width - nw) / 2, 0, nw, height);
|
||||
} else {
|
||||
draw_sprite_scaled(bg, sprites[1], 0, (height - nh) / 2, width, nh);
|
||||
draw_sprite_scaled(bg, wallpaper, 0, (height - nh) / 2, width, nh);
|
||||
}
|
||||
|
||||
/* Three box blurs = good enough approximation of a guassian, but faster*/
|
||||
@ -164,16 +270,13 @@ int main (int argc, char ** argv) {
|
||||
blur_context_box(bg, 20);
|
||||
|
||||
free(bg);
|
||||
free(wallpaper);
|
||||
}
|
||||
|
||||
bg_surf = cairo_image_surface_create_for_data((void*)bg_sprite->bitmap, CAIRO_FORMAT_ARGB32, bg_sprite->width, bg_sprite->height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, bg_sprite->width));
|
||||
|
||||
cairo_surface_t * cs = cairo_image_surface_create_for_data((void*)ctx->backbuffer, CAIRO_FORMAT_ARGB32, ctx->width, ctx->height, cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, ctx->width));
|
||||
cairo_t * cr = cairo_create(cs);
|
||||
|
||||
while (1) {
|
||||
|
||||
yutani_set_stack(y, wina, 0);
|
||||
yutani_focus_window(y, wina->wid);
|
||||
|
||||
draw_fill(ctx, rgb(0,0,0));
|
||||
draw_sprite(ctx, bg_sprite, center_x(width), center_y(height));
|
||||
@ -185,9 +288,9 @@ int main (int argc, char ** argv) {
|
||||
|
||||
for (int i = 0; i < LOGO_FINAL_OFFSET; i += 2) {
|
||||
memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
|
||||
draw_sprite(ctx, sprites[0], center_x(sprites[0]->width), center_y(sprites[0]->height) - i);
|
||||
draw_sprite(ctx, &logo, center_x(logo.width), center_y(logo.height) - i);
|
||||
flip(ctx);
|
||||
yutani_flip_region(y, wina, center_x(sprites[0]->width), center_y(sprites[0]->height) - i, sprites[0]->width, sprites[0]->height + 5);
|
||||
yutani_flip_region(y, wina, center_x(logo.width), center_y(logo.height) - i, logo.width, logo.height + 5);
|
||||
usleep(10000);
|
||||
}
|
||||
|
||||
@ -198,7 +301,6 @@ int main (int argc, char ** argv) {
|
||||
|
||||
uint32_t black = rgb(0,0,0);
|
||||
uint32_t white = rgb(255,255,255);
|
||||
uint32_t red = rgb(240, 20, 20);
|
||||
|
||||
int x_offset = 65;
|
||||
int y_offset = 64;
|
||||
@ -236,112 +338,144 @@ int main (int argc, char ** argv) {
|
||||
|
||||
uid = 0;
|
||||
|
||||
#define BOX_WIDTH 272
|
||||
#define BOX_HEIGHT 104
|
||||
#define USERNAME_BOX 1
|
||||
#define PASSWORD_BOX 2
|
||||
#define EXTRA_TEXT_OFFSET 12
|
||||
#define TEXTBOX_INTERIOR_LEFT 4
|
||||
#define LEFT_OFFSET 80
|
||||
int box_x = center_x(BOX_WIDTH);
|
||||
int box_y = center_y(0) + 8;
|
||||
|
||||
int focus = USERNAME_BOX;
|
||||
int focus = 0;
|
||||
|
||||
set_font_size(11);
|
||||
|
||||
int username_label_left = LEFT_OFFSET - 2 - draw_string_width("Username:");
|
||||
int password_label_left = LEFT_OFFSET - 2 - draw_string_width("Password:");
|
||||
int hostname_label_left = width - 10 - draw_string_width(hostname);
|
||||
int kernel_v_label_left = 10;
|
||||
|
||||
char password_circles[INPUT_SIZE * 3];
|
||||
struct text_box username_box = { (BOX_WIDTH - 170) / 2, 30, 170, 20, rgb(0,0,0), NULL, 0, 0, 0, username, "Username" };
|
||||
struct text_box password_box = { (BOX_WIDTH - 170) / 2, 58, 170, 20, rgb(0,0,0), NULL, 0, 1, 0, password, "Password" };
|
||||
|
||||
int show_error = 0;
|
||||
struct login_container lc = { box_x, box_y, BOX_WIDTH, BOX_HEIGHT, &username_box, &password_box, 0 };
|
||||
|
||||
username_box.parent = &lc;
|
||||
password_box.parent = &lc;
|
||||
|
||||
while (1) {
|
||||
focus = USERNAME_BOX;
|
||||
focus = 0;
|
||||
memset(username, 0x0, INPUT_SIZE);
|
||||
memset(password, 0x0, INPUT_SIZE);
|
||||
memset(password_circles, 0x0, INPUT_SIZE * 3);
|
||||
|
||||
while (1) {
|
||||
|
||||
strcpy(password_circles, "");
|
||||
for (int i = 0; i < strlen(password); ++i) {
|
||||
strcat(password_circles, "●");
|
||||
}
|
||||
|
||||
memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
|
||||
draw_sprite(ctx, sprites[0], center_x(sprites[0]->width), center_y(sprites[0]->height) - LOGO_FINAL_OFFSET);
|
||||
draw_sprite(ctx, &logo, center_x(logo.width), center_y(logo.height) - LOGO_FINAL_OFFSET);
|
||||
|
||||
set_font_size(11);
|
||||
draw_string_shadow(ctx, hostname_label_left, height - 12, white, hostname, rgb(0,0,0), 2, 1, 1, 3.0);
|
||||
draw_string_shadow(ctx, kernel_v_label_left, height - 12, white, kernel_v, rgb(0,0,0), 2, 1, 1, 3.0);
|
||||
|
||||
/* Draw backdrops */
|
||||
draw_box(ctx, box_x, box_y, BOX_WIDTH, BOX_HEIGHT, rgb(20,20,20));
|
||||
draw_box(ctx, box_x + LEFT_OFFSET, box_y + 32, 168, 16, rgb(255,255,255));
|
||||
draw_box(ctx, box_x + LEFT_OFFSET, box_y + 56, 168, 16, rgb(255,255,255));
|
||||
|
||||
/* Draw labels */
|
||||
draw_string(ctx, box_x + username_label_left, box_y + 32 + EXTRA_TEXT_OFFSET, white, "Username:");
|
||||
draw_string(ctx, box_x + password_label_left, box_y + 56 + EXTRA_TEXT_OFFSET, white, "Password:");
|
||||
|
||||
/* Draw box entries */
|
||||
draw_string(ctx, box_x + LEFT_OFFSET + TEXTBOX_INTERIOR_LEFT, box_y + 32 + EXTRA_TEXT_OFFSET, black, username);
|
||||
draw_string(ctx, box_x + LEFT_OFFSET + TEXTBOX_INTERIOR_LEFT, box_y + 56 + EXTRA_TEXT_OFFSET, black, password_circles);
|
||||
|
||||
if (show_error) {
|
||||
char * error_message = "Incorrect username or password.";
|
||||
|
||||
draw_string(ctx, box_x + (BOX_WIDTH - draw_string_width(error_message)) / 2, box_y + 8 + EXTRA_TEXT_OFFSET, red, error_message);
|
||||
}
|
||||
|
||||
if (focus == USERNAME_BOX) {
|
||||
draw_box_border(ctx, box_x + LEFT_OFFSET, box_y + 32, 168, 16, rgb(8, 193, 236));
|
||||
username_box.is_focused = 1;
|
||||
password_box.is_focused = 0;
|
||||
} else if (focus == PASSWORD_BOX) {
|
||||
draw_box_border(ctx, box_x + LEFT_OFFSET, box_y + 56, 168, 16, rgb(8, 193, 236));
|
||||
username_box.is_focused = 0;
|
||||
password_box.is_focused = 1;
|
||||
} else {
|
||||
username_box.is_focused = 0;
|
||||
password_box.is_focused = 0;
|
||||
}
|
||||
|
||||
draw_login_container(cr, &lc);
|
||||
|
||||
flip(ctx);
|
||||
yutani_flip(y, wina);
|
||||
|
||||
struct yutani_msg_key_event kbd;
|
||||
int tmp = 0;
|
||||
struct yutani_msg_window_mouse_event mou;
|
||||
int msg_type = 0;
|
||||
do {
|
||||
yutani_msg_t * msg = yutani_poll(y);
|
||||
if (msg->type == YUTANI_MSG_KEY_EVENT) {
|
||||
struct yutani_msg_key_event * ke = (void*)msg->data;
|
||||
if (ke->event.action == KEY_ACTION_DOWN) {
|
||||
memcpy(&kbd, ke, sizeof(struct yutani_msg_key_event));
|
||||
tmp = 1;
|
||||
}
|
||||
switch (msg->type) {
|
||||
case YUTANI_MSG_KEY_EVENT:
|
||||
{
|
||||
struct yutani_msg_key_event * ke = (void*)msg->data;
|
||||
if (ke->event.action == KEY_ACTION_DOWN) {
|
||||
memcpy(&kbd, ke, sizeof(struct yutani_msg_key_event));
|
||||
msg_type = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case YUTANI_MSG_WINDOW_MOUSE_EVENT:
|
||||
{
|
||||
struct yutani_msg_window_mouse_event * me = (void*)msg->data;
|
||||
memcpy(&mou, me, sizeof(struct yutani_msg_mouse_event));
|
||||
msg_type = 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
free(msg);
|
||||
} while (!tmp);
|
||||
} while (!msg_type);
|
||||
|
||||
if (kbd.event.keycode == '\n') {
|
||||
if (focus == USERNAME_BOX) {
|
||||
focus = PASSWORD_BOX;
|
||||
if (msg_type == 1) {
|
||||
|
||||
if (kbd.event.keycode == '\n') {
|
||||
if (focus == USERNAME_BOX) {
|
||||
focus = PASSWORD_BOX;
|
||||
continue;
|
||||
} else if (focus == PASSWORD_BOX) {
|
||||
break;
|
||||
} else {
|
||||
focus = USERNAME_BOX;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (kbd.event.keycode == '\t') {
|
||||
if (focus == USERNAME_BOX) {
|
||||
focus = PASSWORD_BOX;
|
||||
} else {
|
||||
focus = USERNAME_BOX;
|
||||
}
|
||||
continue;
|
||||
} else if (focus == PASSWORD_BOX) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (kbd.event.keycode == '\t') {
|
||||
if (focus == USERNAME_BOX) {
|
||||
focus = PASSWORD_BOX;
|
||||
} else if (focus == PASSWORD_BOX) {
|
||||
focus = USERNAME_BOX;
|
||||
if (kbd.event.key) {
|
||||
|
||||
if (!focus) {
|
||||
focus = USERNAME_BOX;
|
||||
}
|
||||
|
||||
if (focus == USERNAME_BOX) {
|
||||
buffer_put(username, kbd.event.key);
|
||||
} else if (focus == PASSWORD_BOX) {
|
||||
buffer_put(password, kbd.event.key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
} else if (msg_type == 2) {
|
||||
|
||||
if ((mou.command == YUTANI_MOUSE_EVENT_DOWN
|
||||
&& mou.buttons & YUTANI_MOUSE_BUTTON_LEFT)
|
||||
|| (mou.command == YUTANI_MOUSE_EVENT_CLICK)) {
|
||||
/* Determine if we were inside of a text box */
|
||||
|
||||
if (mou.new_x >= lc.x + username_box.x &&
|
||||
mou.new_x <= lc.x + username_box.x + username_box.width &&
|
||||
mou.new_y >= lc.y + username_box.y &&
|
||||
mou.new_y <= lc.y + username_box.y + username_box.height) {
|
||||
/* Ensure this box is focused. */
|
||||
focus = USERNAME_BOX;
|
||||
continue;
|
||||
} else if (mou.new_x >= lc.x + password_box.x &&
|
||||
mou.new_x <= lc.x + password_box.x + password_box.width &&
|
||||
mou.new_y >= lc.y + password_box.y &&
|
||||
mou.new_y <= lc.y + password_box.y + password_box.height) {
|
||||
/* Ensure this box is focused. */
|
||||
focus = PASSWORD_BOX;
|
||||
continue;
|
||||
} else {
|
||||
focus = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (focus == USERNAME_BOX) {
|
||||
buffer_put(username, kbd.event.keycode);
|
||||
} else if (focus == PASSWORD_BOX) {
|
||||
buffer_put(password, kbd.event.keycode);
|
||||
}
|
||||
|
||||
}
|
||||
@ -351,7 +485,7 @@ int main (int argc, char ** argv) {
|
||||
if (uid >= 0) {
|
||||
break;
|
||||
}
|
||||
show_error = 1;
|
||||
lc.show_error = 1;
|
||||
}
|
||||
|
||||
memcpy(ctx->backbuffer, foo, sizeof(uint32_t) * width * height);
|
||||
|
Loading…
Reference in New Issue
Block a user