@ -39,14 +39,124 @@ struct virtual_keyboard {
struct display * display ;
} ;
enum key_type {
keytype_default ,
keytype_backspace ,
keytype_enter ,
keytype_space ,
keytype_switch ,
keytype_symbols ,
keytype_tab
} ;
struct key {
enum key_type key_type ;
char * label ;
char * alt ;
unsigned int width ;
} ;
static const struct key keys [ ] = {
{ keytype_default , " q " , " Q " , 1 } ,
{ keytype_default , " w " , " W " , 1 } ,
{ keytype_default , " e " , " E " , 1 } ,
{ keytype_default , " r " , " R " , 1 } ,
{ keytype_default , " t " , " T " , 1 } ,
{ keytype_default , " y " , " Y " , 1 } ,
{ keytype_default , " u " , " U " , 1 } ,
{ keytype_default , " i " , " I " , 1 } ,
{ keytype_default , " o " , " O " , 1 } ,
{ keytype_default , " p " , " P " , 1 } ,
{ keytype_backspace , " <-- " , " <-- " , 2 } ,
{ keytype_tab , " ->| " , " ->| " , 1 } ,
{ keytype_default , " a " , " A " , 1 } ,
{ keytype_default , " s " , " S " , 1 } ,
{ keytype_default , " d " , " D " , 1 } ,
{ keytype_default , " f " , " F " , 1 } ,
{ keytype_default , " g " , " G " , 1 } ,
{ keytype_default , " h " , " H " , 1 } ,
{ keytype_default , " j " , " J " , 1 } ,
{ keytype_default , " k " , " K " , 1 } ,
{ keytype_default , " l " , " L " , 1 } ,
{ keytype_enter , " Enter " , " Enter " , 2 } ,
{ keytype_switch , " ABC " , " abc " , 2 } ,
{ keytype_default , " z " , " Z " , 1 } ,
{ keytype_default , " x " , " X " , 1 } ,
{ keytype_default , " c " , " C " , 1 } ,
{ keytype_default , " v " , " V " , 1 } ,
{ keytype_default , " b " , " B " , 1 } ,
{ keytype_default , " n " , " N " , 1 } ,
{ keytype_default , " m " , " M " , 1 } ,
{ keytype_default , " , " , " , " , 1 } ,
{ keytype_default , " . " , " . " , 1 } ,
{ keytype_switch , " ABC " , " abc " , 1 } ,
{ keytype_symbols , " ?123 " , " ?123 " , 2 } ,
{ keytype_space , " " , " " , 8 } ,
{ keytype_symbols , " ?123 " , " ?123 " , 2 }
} ;
static const unsigned int columns = 12 ;
static const unsigned int rows = 4 ;
static const double key_width = 60 ;
static const double key_height = 50 ;
enum keyboard_state {
keyboardstate_default ,
keyboardstate_uppercase
} ;
struct keyboard {
struct virtual_keyboard * keyboard ;
struct window * window ;
struct widget * widget ;
int cx ;
int cy ;
enum keyboard_state state ;
} ;
static void
draw_key ( const struct key * key ,
cairo_t * cr ,
enum keyboard_state state ,
unsigned int row ,
unsigned int col )
{
const char * label ;
cairo_text_extents_t extents ;
cairo_save ( cr ) ;
cairo_rectangle ( cr ,
col * key_width , row * key_height ,
key - > width * key_width , key_height ) ;
cairo_clip ( cr ) ;
/* Paint frame */
cairo_rectangle ( cr ,
col * key_width , row * key_height ,
key - > width * key_width , key_height ) ;
cairo_set_line_width ( cr , 3 ) ;
cairo_stroke ( cr ) ;
/* Paint text */
label = state = = keyboardstate_default ? key - > label : key - > alt ;
cairo_text_extents ( cr , label , & extents ) ;
cairo_translate ( cr ,
col * key_width ,
row * key_height ) ;
cairo_translate ( cr ,
( key - > width * key_width - extents . width ) / 2 ,
( key_height - extents . y_bearing ) / 2 ) ;
cairo_show_text ( cr , label ) ;
cairo_restore ( cr ) ;
}
static void
redraw_handler ( struct widget * widget , void * data )
{
@ -54,8 +164,8 @@ redraw_handler(struct widget *widget, void *data)
cairo_surface_t * surface ;
struct rectangle allocation ;
cairo_t * cr ;
int cx , cy ;
int i ;
unsigned int i ;
unsigned int row = 0 , col = 0 ;
surface = window_get_surface ( keyboard - > window ) ;
widget_get_allocation ( keyboard - > widget , & allocation ) ;
@ -64,37 +174,26 @@ redraw_handler(struct widget *widget, void *data)
cairo_rectangle ( cr , allocation . x , allocation . y , allocation . width , allocation . height ) ;
cairo_clip ( cr ) ;
cairo_translate ( cr , allocation . x , allocation . y ) ;
cairo_select_font_face ( cr , " sans " , CAIRO_FONT_SLANT_NORMAL , CAIRO_FONT_WEIGHT_BOLD ) ;
cairo_set_font_size ( cr , 16 ) ;
cx = keyboard - > cx ;
cy = keyboard - > cy ;
cairo_translate ( cr , allocation . x , allocation . y ) ;
cairo_set_operator ( cr , CAIRO_OPERATOR_SOURCE ) ;
cairo_set_source_rgba ( cr , 1 , 1 , 1 , 0.5 ) ;
cairo_rectangle ( cr , 0 , 0 , 10 * cx , 5 * cy ) ;
cairo_set_source_rgba ( cr , 1 , 1 , 1 , 0.7 5 ) ;
cairo_rectangle ( cr , 0 , 0 , columns * key_width , rows * key_height ) ;
cairo_paint ( cr ) ;
cairo_set_operator ( cr , CAIRO_OPERATOR_OVER ) ;
for ( i = 0 ; i < = ' Z ' - ' 0 ' ; + + i ) {
const int x = i % 10 ;
const int y = i / 10 ;
char text [ ] = { i + ' 0 ' , ' \0 ' } ;
cairo_text_extents_t extents ;
int dx , dy ;
cairo_text_extents ( cr , text , & extents ) ;
dx = extents . width ;
dy = extents . height ;
cairo_set_source_rgb ( cr , 0 , 0 , 0 ) ;
cairo_rectangle ( cr , x * cx , y * cy , cx , cy ) ;
cairo_stroke ( cr ) ;
cairo_move_to ( cr , x * cx + 0.5 * ( cx - dx ) , y * cy + 0.5 * ( cy - dy ) ) ;
for ( i = 0 ; i < sizeof ( keys ) / sizeof ( * keys ) ; + + i ) {
cairo_set_source_rgb ( cr , 0 , 0 , 0 ) ;
cairo_show_text ( cr , text ) ;
draw_key ( & keys [ i ] , cr , keyboard - > state , row , col ) ;
col + = keys [ i ] . width ;
if ( col > = columns ) {
row + = 1 ;
col = 0 ;
}
}
cairo_destroy ( cr ) ;
@ -108,6 +207,37 @@ resize_handler(struct widget *widget,
/* struct keyboard *keyboard = data; */
}
static void
keyboard_handle_key ( struct keyboard * keyboard , const struct key * key )
{
const char * label = keyboard - > state = = keyboardstate_default ? key - > label : key - > alt ;
switch ( key - > key_type ) {
case keytype_default :
input_method_context_commit_string ( keyboard - > keyboard - > context ,
label , - 1 ) ;
break ;
case keytype_backspace :
break ;
case keytype_enter :
break ;
case keytype_space :
input_method_context_commit_string ( keyboard - > keyboard - > context ,
" " , - 1 ) ;
break ;
case keytype_switch :
if ( keyboard - > state = = keyboardstate_default )
keyboard - > state = keyboardstate_uppercase ;
else
keyboard - > state = keyboardstate_default ;
break ;
case keytype_symbols :
break ;
case keytype_tab :
break ;
}
}
static void
button_handler ( struct widget * widget ,
struct input * input , uint32_t time ,
@ -116,8 +246,9 @@ button_handler(struct widget *widget,
{
struct keyboard * keyboard = data ;
struct rectangle allocation ;
int32_t x , y ;
char text [ ] = { ' 0 ' , ' \0 ' } ;
int32_t x , y ;
int row , col ;
unsigned int i ;
if ( state ! = WL_POINTER_BUTTON_STATE_PRESSED | | button ! = BTN_LEFT ) {
return ;
@ -129,9 +260,15 @@ button_handler(struct widget *widget,
x - = allocation . x ;
y - = allocation . y ;
text [ 0 ] = y / keyboard - > cy * 10 + x / keyboard - > cx + ' 0 ' ;
row = y / key_height ;
col = x / key_width + row * columns ;
for ( i = 0 ; i < sizeof ( keys ) / sizeof ( * keys ) ; + + i ) {
col - = keys [ i ] . width ;
if ( col < 0 )
break ;
}
input_method_context_commit_string ( keyboard - > keyboard - > context , text , - 1 ) ;
keyboard_handle_key ( keyboard , & keys [ i ] ) ;
widget_schedule_redraw ( widget ) ;
}
@ -213,15 +350,14 @@ keyboard_create(struct output *output, struct virtual_keyboard *virtual_keyboard
window_set_title ( keyboard - > window , " Virtual keyboard " ) ;
window_set_user_data ( keyboard - > window , keyboard ) ;
keyboard - > cx = 40 ;
keyboard - > cy = 40 ;
widget_set_redraw_handler ( keyboard - > widget , redraw_handler ) ;
widget_set_resize_handler ( keyboard - > widget , resize_handler ) ;
widget_set_button_handler ( keyboard - > widget , button_handler ) ;
window_schedule_resize ( keyboard - > window , keyboard - > cx * 10 , keyboard - > cy * 5 ) ;
window_schedule_resize ( keyboard - > window ,
columns * key_width ,
rows * key_height ) ;
input_panel_set_surface ( virtual_keyboard - > input_panel ,
window_get_wl_surface ( keyboard - > window ) ,