diff --git a/clients/keyboard.c b/clients/keyboard.c index d62969fde..ff21136a2 100644 --- a/clients/keyboard.c +++ b/clients/keyboard.c @@ -247,6 +247,9 @@ static const struct layout arabic_layout = { ZWP_TEXT_INPUT_V1_TEXT_DIRECTION_RTL }; +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) +#define max_count MAX(MAX(sizeof(arabic_keys) / sizeof(*arabic_keys), sizeof(numeric_keys) / sizeof(*numeric_keys) ), sizeof(normal_keys) / sizeof(*normal_keys)) + static const char *style_labels[] = { "default", "none", @@ -273,6 +276,8 @@ struct keyboard { struct widget *widget; enum keyboard_state state; + uint32_t key_state[max_count]; + uint32_t key_margin; uint32_t key_radius; @@ -300,6 +305,16 @@ dbg(const char *fmt, ...) #endif } +static void +set_hex_color(cairo_t *cr, uint32_t color) +{ + cairo_set_source_rgba(cr, + ((color >> 16) & 0xff) / 255.0, + ((color >> 8) & 0xff) / 255.0, + ((color >> 0) & 0xff) / 255.0, + ((color >> 24) & 0xff) / 255.0); +} + static const char * label_from_key(struct keyboard *keyboard, const struct key *key) @@ -322,16 +337,42 @@ label_from_key(struct keyboard *keyboard, return ""; } +static void +rounded_rectangle_path(cairo_t *cr, double x, double y, double width, double height, double radius) +{ + double degrees = M_PI / 180.0; + + cairo_new_sub_path (cr); + cairo_arc (cr, x + width - radius, y + radius, radius, -90 * degrees, 0 * degrees); + cairo_arc (cr, x + width - radius, y + height - radius, radius, 0 * degrees, 90 * degrees); + cairo_arc (cr, x + radius, y + height - radius, radius, 90 * degrees, 180 * degrees); + cairo_arc (cr, x + radius, y + radius, radius, 180 * degrees, 270 * degrees); + cairo_close_path (cr); +} + static void draw_key(struct keyboard *keyboard, const struct key *key, + uint32_t key_state, cairo_t *cr, unsigned int row, unsigned int col) { + const uint32_t margin = keyboard->key_margin; const char *label; cairo_text_extents_t extents; + uint32_t fg_color = keyboard->key_fg_color; + uint32_t bg_color = keyboard->key_bg_color; + + if (key_state == WL_KEYBOARD_KEY_STATE_RELEASED) { + fg_color = (key->key_type == keytype_default ? keyboard->key_fg_color : keyboard->special_key_fg_color); + bg_color = (key->key_type == keytype_default ? keyboard->key_bg_color : keyboard->special_key_bg_color); + } else { + fg_color = (key->key_type == keytype_default ? keyboard->key_pressed_fg_color : keyboard->special_key_pressed_fg_color); + bg_color = (key->key_type == keytype_default ? keyboard->key_pressed_bg_color : keyboard->special_key_pressed_bg_color); + } + if (key->key_type == keytype_none) return; @@ -340,11 +381,18 @@ draw_key(struct keyboard *keyboard, col * key_width, row * key_height, key->width * key_width, key_height); cairo_clip(cr); + rounded_rectangle_path(cr, + col * key_width + margin, row * key_height + margin, + key->width * key_width - 2*margin, key_height - 2*margin, + key_width / 5); + + + /* Paint key background */ + set_hex_color(cr, bg_color); + cairo_fill_preserve(cr); /* Paint frame */ - cairo_rectangle(cr, - col * key_width, row * key_height, - key->width * key_width, key_height); + set_hex_color(cr, fg_color); cairo_set_line_width(cr, 3); cairo_stroke(cr); @@ -405,15 +453,16 @@ redraw_handler(struct widget *widget, void *data) cairo_translate(cr, allocation.x, allocation.y); cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); - cairo_set_source_rgba(cr, 1, 1, 1, 0.75); cairo_rectangle(cr, 0, 0, layout->columns * key_width, layout->rows * key_height); - cairo_paint(cr); + set_hex_color(cr, keyboard->panel_bg_color); + cairo_fill_preserve(cr); + set_hex_color(cr, keyboard->panel_fg_color); + cairo_stroke(cr); cairo_set_operator(cr, CAIRO_OPERATOR_OVER); for (i = 0; i < layout->count; ++i) { - cairo_set_source_rgb(cr, 0, 0, 0); - draw_key(keyboard, &layout->keys[i], cr, row, col); + draw_key(keyboard, &layout->keys[i], keyboard->key_state[i], cr, row, col); col += layout->keys[i].width; if (col >= layout->columns) { row += 1; @@ -557,7 +606,7 @@ append(char *s1, const char *s2) } static void -keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, struct input *input, enum wl_pointer_button_state state) +keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key *key, uint32_t key_num, struct input *input, enum wl_pointer_button_state state) { const char *label = NULL; @@ -576,6 +625,8 @@ keyboard_handle_key(struct keyboard *keyboard, uint32_t time, const struct key * xkb_mod_mask_t mod_mask = keyboard->state == KEYBOARD_STATE_DEFAULT ? 0 : keyboard->keyboard->keysym.shift_mask; uint32_t key_state = (state == WL_POINTER_BUTTON_STATE_PRESSED) ? WL_KEYBOARD_KEY_STATE_PRESSED : WL_KEYBOARD_KEY_STATE_RELEASED; + keyboard->key_state[key_num] = key_state; + switch (key->key_type) { case keytype_default: if (state != WL_POINTER_BUTTON_STATE_PRESSED) @@ -717,7 +768,7 @@ button_handler(struct widget *widget, for (i = 0; i < layout->count; ++i) { col -= layout->keys[i].width; if (col < 0) { - keyboard_handle_key(keyboard, time, &layout->keys[i], input, state); + keyboard_handle_key(keyboard, time, &layout->keys[i], i, input, state); break; } } @@ -748,7 +799,7 @@ touch_handler(struct input *input, uint32_t time, col -= layout->keys[i].width; if (col < 0) { keyboard_handle_key(keyboard, time, - &layout->keys[i], input, state); + &layout->keys[i], i, input, state); break; } }