File keypad_update.patch of Package pw3270
diff -Naur pw3270-5.0/src/pw3270/uiparser/button.c pw3270-5.0/src/pw3270/uiparser/button.c
--- pw3270-5.0/src/pw3270/uiparser/button.c 2016-04-18 08:58:50.000000000 -0300
+++ pw3270-5.0/src/pw3270/uiparser/button.c 2016-10-21 16:19:41.193388809 -0200
@@ -82,41 +82,27 @@
const gchar * name = ui_get_attribute("action", names, values);
struct parser * info = keypad->parser;
GtkAction * action = NULL;
- GtkWidget * widget = NULL;
- if(++keypad->col > keypad->num_cols)
- keypad->num_cols = keypad->col;
-
- keypad->row->num_cols++;
-
- if(label)
- {
- widget = gtk_button_new_with_label(gettext(g_strcompress(label)));
- }
- else if(icon)
- {
+ if(label) {
+ keypad->widget = gtk_button_new_with_label(gettext(g_strcompress(label)));
+ } else {
gchar *text = g_strconcat("gtk-",icon,NULL);
- widget = gtk_button_new();
- gtk_container_add(GTK_CONTAINER(widget),gtk_image_new_from_stock(text,GTK_ICON_SIZE_SMALL_TOOLBAR));
+ keypad->widget = gtk_button_new();
+ gtk_container_add(GTK_CONTAINER(keypad->widget),gtk_image_new_from_stock(text,GTK_ICON_SIZE_SMALL_TOOLBAR));
g_free(text);
}
- keypad->row->cols = g_list_append(keypad->row->cols,widget);
-
- if(!widget)
- return;
-
#if GTK_CHECK_VERSION(2,18,0)
- gtk_widget_set_can_focus(widget,FALSE);
- gtk_widget_set_can_default(widget,FALSE);
+ gtk_widget_set_can_focus(keypad->widget,FALSE);
+ gtk_widget_set_can_default(keypad->widget,FALSE);
#else
- GTK_WIDGET_UNSET_FLAGS(widget,GTK_CAN_FOCUS);
- GTK_WIDGET_UNSET_FLAGS(widget,GTK_CAN_DEFAULT);
+ GTK_WIDGET_UNSET_FLAGS(keypad->widget,GTK_CAN_FOCUS);
+ GTK_WIDGET_UNSET_FLAGS(keypad->widget,GTK_CAN_DEFAULT);
#endif // GTK(2,18)
- gtk_button_set_relief(GTK_BUTTON(widget),ui_get_relief(names, values, keypad->relief));
- gtk_button_set_alignment(GTK_BUTTON(widget),0.5,0.5);
- gtk_button_set_focus_on_click(GTK_BUTTON(widget),FALSE);
+ gtk_button_set_relief(GTK_BUTTON(keypad->widget),ui_get_relief(names, values, keypad->relief));
+ gtk_button_set_alignment(GTK_BUTTON(keypad->widget),0.5,0.5);
+ gtk_button_set_focus_on_click(GTK_BUTTON(keypad->widget),FALSE);
if(name)
action = ui_get_action(info->center_widget,name,info->actions,names,values,error);
@@ -124,13 +110,13 @@
if(action)
{
ui_action_set_options(action,info,names,values,error);
- g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(button_clicked),action);
+ g_signal_connect(G_OBJECT(keypad->widget),"clicked",G_CALLBACK(button_clicked),action);
}
else
{
- keypad->widget = widget;
- gtk_widget_set_sensitive(widget,FALSE);
- g_signal_connect(G_OBJECT(widget),"clicked",G_CALLBACK(button_script),info->center_widget);
+ gtk_widget_set_sensitive(keypad->widget,FALSE);
+ g_signal_connect(G_OBJECT(keypad->widget),"clicked",G_CALLBACK(button_script),info->center_widget);
}
+
}
diff -Naur pw3270-5.0/src/pw3270/uiparser/keypad.c pw3270-5.0/src/pw3270/uiparser/keypad.c
--- pw3270-5.0/src/pw3270/uiparser/keypad.c 2016-04-18 08:58:50.000000000 -0300
+++ pw3270-5.0/src/pw3270/uiparser/keypad.c 2016-10-21 16:16:39.420377213 -0200
@@ -28,49 +28,82 @@
*/
#include "keypad.h"
+ #include <stdlib.h>
/*--[ Implement ]------------------------------------------------------------------------------------*/
- void keypad_row_start(GMarkupParseContext *context, const gchar **names,const gchar **values, GError **error, struct keypad *keypad)
+ static void element_start(GMarkupParseContext *context, const gchar *element_name, const gchar **names,const gchar **values, struct keypad *keypad, GError **error)
{
- keypad->row = g_malloc0(sizeof(struct row));
+ int width = 1;
+ int height = 1;
+ const gchar * tmp;
- keypad->row->pos = ++keypad->num_rows;
- keypad->col = 0;
+ trace("%s(%s,%d,%d)",__FUNCTION__,element_name,(int) keypad->row, (int) keypad->col);
- keypad->rows = g_list_append(keypad->rows,keypad->row);
- }
+ keypad->widget = NULL;
- static void element_start(GMarkupParseContext *context, const gchar *element_name, const gchar **names,const gchar **values, struct keypad *keypad, GError **error)
- {
- static const struct _cmd
- {
- const gchar *element_name;
- void (*start)(GMarkupParseContext *, const gchar **,const gchar **, GError **, struct keypad *);
- } cmd[] =
- {
- { "row", keypad_row_start },
- { "button", keypad_button_start },
- };
+ if(!strcasecmp(element_name,"button")) {
+ keypad_button_start(context, names, values, error, keypad);
+ }
- int f;
+ tmp = ui_get_attribute("width", names, values);
+ if(tmp) {
+ width = atoi(tmp);
+ }
- for(f = 0; f < G_N_ELEMENTS(cmd); f++)
- {
- if(!g_ascii_strcasecmp(cmd[f].element_name,element_name))
- {
- cmd[f].start(context,names,values,error,keypad);
- return;
- }
+ tmp = ui_get_attribute("height", names, values);
+ if(tmp) {
+ height = atoi(tmp);
}
- *error = g_error_new(ERROR_DOMAIN,EINVAL, _( "Unexpected element <%s>"), element_name);
+ if(keypad->widget) {
+
+ // Criou widget, incluir
+ tmp = ui_get_attribute("column", names, values);
+ if(tmp) {
+ keypad->col = atoi(tmp);
+ }
+
+#if GTK_CHECK_VERSION(3,0,0)
+
+ gtk_grid_attach(keypad->grid,keypad->widget,keypad->col,keypad->row,width,height);
+
+#else
+ guint r = keypad->rows, c = keypad->cols;
+
+ if(r < keypad->row || c < (keypad->col+1)) {
+ trace("Resize to %u,%u to %u,%u",r,c,keypad->row,keypad->col+1);
+ gtk_table_resize(keypad->grid,keypad->rows = keypad->row,keypad->cols = (keypad->col+1));
+ }
+
+ r = keypad->row-1;
+ c = keypad->col;
+
+ gtk_table_attach( keypad->grid,
+ keypad->widget,
+ c,c+width,
+ r,r+height,
+ GTK_EXPAND|GTK_FILL,
+ GTK_EXPAND|GTK_FILL,
+ 1,1);
+#endif
+
+ keypad->widget = NULL;
+
+ }
+
+ if(!strcasecmp(element_name,"row")) {
+ keypad->row += height;
+ keypad->col = 0;
+ } else {
+ keypad->col += width;
+ }
+
}
static void element_end(GMarkupParseContext *context, const gchar *element_name, struct keypad *keypad, GError **error)
{
- keypad->widget = NULL;
-// trace("%s: %s",__FUNCTION__,element_name);
+
}
static void toggled(GtkToggleAction *action, GtkWidget *widget)
@@ -88,44 +121,37 @@
}
- UI_ATTR_DIRECTION ui_get_position_attribute(const gchar **names, const gchar **values)
+ GtkPositionType ui_get_position_attribute(const gchar **names, const gchar **values)
{
- static const gchar * posname[] = { "top", "bottom", "left", "right" };
- const gchar * dir = ui_get_attribute("position",names,values);
- int f;
+ static const struct _pos {
+ GtkPositionType type;
+ const gchar * name;
+ } pos [] = {
+
+ { GTK_POS_LEFT, "left" },
+ { GTK_POS_RIGHT, "right" },
+ { GTK_POS_TOP, "top" },
+ { GTK_POS_BOTTOM, "bottom" },
+
+ };
+
+ const gchar * dir = ui_get_attribute("position",names,values);
+ int f;
if(dir)
{
- for(f=0;f<G_N_ELEMENTS(posname);f++)
+ for(f=0;f<G_N_ELEMENTS(pos);f++)
{
- if(!g_ascii_strcasecmp(dir,posname[f]))
- return f;
+ if(!g_ascii_strcasecmp(dir,pos[f].name))
+ return pos[f].type;
}
}
- return UI_ATTR_DIRECTION_NONE;
+ return GTK_POS_TOP;
}
static void element_text(GMarkupParseContext *context, const gchar *text, gsize sz, struct keypad *keypad, GError **error)
{
- if(keypad->widget)
- {
- gchar *base = g_strstrip(g_strdup(text));
- gchar *text = g_strdup(base);
- g_free(base);
-
- if(*text)
- {
- gtk_widget_set_sensitive(keypad->widget,TRUE);
- g_object_set_data_full(G_OBJECT(keypad->widget),"script_text",text,g_free);
- }
- else
- {
- g_free(text);
- }
-
- }
-
}
GObject * ui_create_keypad(GMarkupParseContext *context,GtkAction *action,struct parser *info,const gchar **names, const gchar **values, GError **error)
@@ -162,100 +188,42 @@
info->block_data = keypad = g_malloc0(sizeof(struct keypad));
keypad->parser = info;
- keypad->handle = gtk_handle_box_new();
keypad->pos = ui_get_position_attribute(names,values);
keypad->relief = ui_get_relief(names, values, GTK_RELIEF_NORMAL);
- switch(keypad->pos)
- {
- case UI_ATTR_UP:
-#if GTK_CHECK_VERSION(3,0,0)
- keypad->box = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
-#else
- keypad->box = gtk_vbox_new(FALSE,0);
-#endif // GTK(3,0,0)
- gtk_handle_box_set_handle_position(GTK_HANDLE_BOX(keypad->handle),GTK_POS_BOTTOM);
- break;
-
- case UI_ATTR_DOWN:
-#if GTK_CHECK_VERSION(3,0,0)
- keypad->box = gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
-#else
- keypad->box = gtk_vbox_new(FALSE,0);
-#endif // GTK(3,0,0)
- gtk_handle_box_set_handle_position(GTK_HANDLE_BOX(keypad->handle),GTK_POS_TOP);
- break;
-
- case UI_ATTR_LEFT:
#if GTK_CHECK_VERSION(3,0,0)
- keypad->box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
-#else
- keypad->box = gtk_hbox_new(FALSE,0);
-#endif // GTK(3,0,0)
- gtk_handle_box_set_handle_position(GTK_HANDLE_BOX(keypad->handle),GTK_POS_RIGHT);
- break;
-
- default:
-#if GTK_CHECK_VERSION(3,0,0)
- keypad->box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
-#else
- keypad->box = gtk_hbox_new(FALSE,0);
-#endif // GTK(3,0,0)
- keypad->pos = UI_ATTR_RIGHT;
- gtk_handle_box_set_handle_position(GTK_HANDLE_BOX(keypad->handle),GTK_POS_LEFT);
+ keypad->grid = GTK_GRID(gtk_grid_new());
+ gtk_grid_set_row_homogeneous(keypad->grid,TRUE);
+ gtk_grid_set_column_homogeneous(keypad->grid,TRUE);
+#else
+ keypad->rows = 1;
+ keypad->cols = 1;
+ keypad->grid = GTK_TABLE(gtk_table_new(keypad->rows,keypad->cols,TRUE));
+#endif // GTK3
- }
+ g_object_set_data(G_OBJECT(keypad->grid),"position",(gpointer) keypad->pos);
label = ui_get_attribute("label",names,values);
if(label)
{
// Keypad has label, create and setup an action
const gchar *name = ui_get_attribute("name",names,values);
+
+ trace("%s name=%s",__FUNCTION__,name);
+
if(name)
{
GtkToggleAction *action = gtk_toggle_action_new(name,gettext(label),NULL,NULL);
ui_action_set_options(GTK_ACTION(action),info,names,values,error);
- g_object_set_data_full(G_OBJECT(keypad->handle),"view_action",action,g_object_unref);
- g_signal_connect(action,"toggled",G_CALLBACK(toggled),keypad->handle);
+ g_object_set_data_full(G_OBJECT(keypad->grid),"view_action",action,g_object_unref);
+ g_signal_connect(action,"toggled",G_CALLBACK(toggled),keypad->grid);
+ gtk_widget_set_name(GTK_WIDGET(keypad->grid),name);
}
}
- gtk_handle_box_set_shadow_type(GTK_HANDLE_BOX(keypad->handle),GTK_SHADOW_ETCHED_IN);
- gtk_container_add(GTK_CONTAINER(keypad->handle),keypad->box);
-
g_markup_parse_context_push(context,(GMarkupParser *) &parser,keypad);
- return G_OBJECT(ui_insert_element(info, action, UI_ELEMENT_KEYPAD, names, values, G_OBJECT(keypad->handle), error));
- }
-
- static void create_col(GtkWidget *widget, struct keypad *keypad)
- {
- if(widget)
- {
- gtk_table_attach( GTK_TABLE(keypad->table),
- widget,
- keypad->col,keypad->col+keypad->button_width,
- keypad->num_rows,keypad->num_rows+1,
- GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,0,0 );
-
- }
- keypad->col += keypad->button_width;
-
- }
-
- static void create_row(struct row *info, struct keypad *keypad)
- {
- if(info->cols)
- {
- keypad->col = 0;
- keypad->button_width = keypad->num_cols / info->num_cols;
-
-// trace("Max cols=%d row cols=%d width=%d",keypad->num_cols,info->num_cols,keypad->button_width);
-
- g_list_foreach(info->cols,(GFunc) create_col,keypad);
- g_list_free(info->cols);
- }
- keypad->num_rows++;
+ return G_OBJECT(ui_insert_element(info, action, UI_ELEMENT_KEYPAD, names, values, G_OBJECT(keypad->grid), error));
}
void ui_end_keypad(GMarkupParseContext *context,GObject *widget,struct parser *info,GError **error)
@@ -263,33 +231,7 @@
struct keypad *keypad = (struct keypad *) info->block_data;
info->block_data = NULL;
- keypad->num_cols *= 2;
-
- if(keypad->rows)
- {
- // Create Widgets & Release memory
- keypad->table = gtk_table_new(keypad->num_rows,keypad->num_cols,FALSE);
-
-#if GTK_CHECK_VERSION(2,18,0)
- gtk_widget_set_can_focus(keypad->table,FALSE);
- gtk_widget_set_can_default(keypad->table,FALSE);
-#else
- GTK_WIDGET_UNSET_FLAGS(keypad->table,GTK_CAN_FOCUS);
- GTK_WIDGET_UNSET_FLAGS(keypad->table,GTK_CAN_DEFAULT);
-#endif // GTK(2,18)
-
- keypad->num_rows = 0;
- g_list_foreach(keypad->rows,(GFunc) create_row,keypad);
-#if GTK_CHECK_VERSION(2,28,0)
- g_list_free_full(keypad->rows,g_free);
-#else
- g_list_foreach(keypad->rows,(GFunc) g_free,NULL);
- g_list_free(keypad->rows);
-#endif // GTK(2,28)
- gtk_box_pack_start(GTK_BOX(keypad->box),keypad->table,FALSE,FALSE,0);
-
- gtk_widget_show_all(keypad->box);
- }
+ gtk_widget_show_all(GTK_WIDGET(keypad->grid));
g_free(keypad);
g_markup_parse_context_pop(context);
diff -Naur pw3270-5.0/src/pw3270/uiparser/keypad.h pw3270-5.0/src/pw3270/uiparser/keypad.h
--- pw3270-5.0/src/pw3270/uiparser/keypad.h 2016-04-18 08:58:50.000000000 -0300
+++ pw3270-5.0/src/pw3270/uiparser/keypad.h 2016-10-21 16:16:35.804376982 -0200
@@ -33,30 +33,20 @@
/*--[ Globals ]--------------------------------------------------------------------------------------*/
- struct row
- {
- unsigned short pos;
- unsigned short num_cols;
- GList * cols;
- };
-
- struct keypad
- {
+ struct keypad {
struct parser * parser;
- unsigned short num_rows;
- unsigned short num_cols;
+ unsigned short row;
unsigned short col;
- unsigned short button_width;
- struct row * row;
- GtkWidget * box;
- GtkWidget * handle;
- GtkWidget * table;
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkGrid * grid;
+#else
+ GtkTable * grid;
+ guint rows;
+ guint cols;
+#endif // GTK3
+ GtkWidget * widget;
GtkReliefStyle relief;
UI_ATTR_DIRECTION pos;
- GList * rows;
-
- GtkWidget * widget;
-
};
G_GNUC_INTERNAL void keypad_button_start(GMarkupParseContext *context, const gchar **names,const gchar **values, GError **error, struct keypad *keypad);
diff -Naur pw3270-5.0/src/pw3270/uiparser/parser.c pw3270-5.0/src/pw3270/uiparser/parser.c
--- pw3270-5.0/src/pw3270/uiparser/parser.c 2016-04-18 08:58:50.000000000 -0300
+++ pw3270-5.0/src/pw3270/uiparser/parser.c 2016-10-21 16:19:54.041389629 -0200
@@ -73,6 +73,7 @@
gtk_box_pack_start(GTK_BOX(p->element),widget,FALSE,FALSE,0);
}
+
struct keypad
{
GtkWidget * box;
@@ -82,10 +83,13 @@
static void pack_keypad(gpointer key, GtkWidget *widget, struct keypad *k)
{
- if(gtk_handle_box_get_handle_position(GTK_HANDLE_BOX(widget)) != k->filter)
+ if((GtkPositionType) g_object_get_data(G_OBJECT(widget),"position") != k->filter) {
return;
+ }
+ trace("%s %s",__FUNCTION__,gtk_widget_get_name(widget));
k->pack(GTK_BOX(k->box),widget,FALSE,FALSE,0);
+
}
static void pack_view(gpointer key, GtkWidget *widget, GtkWidget *parent)
@@ -231,15 +235,17 @@
ui_setup_keypads(p->element_list[UI_ELEMENT_KEYPAD], p->toplevel, p->center_widget);
// Pack top keypads
+ trace("Packing %s keypads","top");
memset(&keypad,0,sizeof(keypad));
keypad.box = vbox;
- keypad.filter = GTK_POS_BOTTOM;
+ keypad.filter = GTK_POS_TOP;
keypad.pack = gtk_box_pack_start;
g_hash_table_foreach(p->element_list[UI_ELEMENT_KEYPAD],(GHFunc) pack_keypad, &keypad);
// Pack left keypads
+ trace("Packing %s keypads","left");
keypad.box = hbox;
- keypad.filter = GTK_POS_RIGHT;
+ keypad.filter = GTK_POS_LEFT;
g_hash_table_foreach(p->element_list[UI_ELEMENT_KEYPAD],(GHFunc) pack_keypad, &keypad);
// Pack & configure center widget
@@ -252,13 +258,15 @@
gtk_box_pack_start(GTK_BOX(hbox),vbox,TRUE,TRUE,0);
// Pack right keypads
- keypad.filter = GTK_POS_LEFT;
+ trace("Packing %s keypads","right");
+ keypad.filter = GTK_POS_RIGHT;
keypad.pack = gtk_box_pack_end;
g_hash_table_foreach(p->element_list[UI_ELEMENT_KEYPAD],(GHFunc) pack_keypad, &keypad);
// Pack bottom keypads
+ trace("Packing %s keypads","bottom");
keypad.box = vbox;
- keypad.filter = GTK_POS_TOP;
+ keypad.filter = GTK_POS_BOTTOM;
g_hash_table_foreach(p->element_list[UI_ELEMENT_KEYPAD],(GHFunc) pack_keypad, &keypad);
// Finish building
diff -Naur pw3270-5.0/ui/10keypad.xml pw3270-5.0/ui/10keypad.xml
--- pw3270-5.0/ui/10keypad.xml 2016-04-18 08:58:51.000000000 -0300
+++ pw3270-5.0/ui/10keypad.xml 2016-10-21 16:17:48.659381630 -0200
@@ -34,64 +34,60 @@
<keypad name="keypad.right" label="Lateral keypad" position="right" key='<alt>k' relief='half' >
<row>
- <button action='pfkey' id='1' label='PF1' />
- <button action='pfkey' id='2' label='PF2' />
- <button action='pfkey' id='3' label='PF3' />
+ <button action='pfkey' id='1' label='PF1' width='2'/>
+ <button action='pfkey' id='2' label='PF2' width='2' />
+ <button action='pfkey' id='3' label='PF3' width='2' />
</row>
<row>
- <button action='pfkey' id='4' label='PF4' />
- <button action='pfkey' id='5' label='PF5' />
- <button action='pfkey' id='6' label='PF6' />
+ <button action='pfkey' id='4' label='PF4' width='2' />
+ <button action='pfkey' id='5' label='PF5' width='2' />
+ <button action='pfkey' id='6' label='PF6' width='2' />
</row>
<row>
- <button action='pfkey' id='7' label='PF7' />
- <button action='pfkey' id='8' label='PF8' />
- <button action='pfkey' id='9' label='PF9' />
+ <button action='pfkey' id='7' label='PF7' width='2' />
+ <button action='pfkey' id='8' label='PF8' width='2' />
+ <button action='pfkey' id='9' label='PF9' width='2' />
</row>
<row>
- <button action='pfkey' id='10' label='PF10' />
- <button action='pfkey' id='11' label='PF11' />
- <button action='pfkey' id='12' label='PF12' />
+ <button action='pfkey' id='10' label='PF10' width='2' />
+ <button action='pfkey' id='11' label='PF11' width='2' />
+ <button action='pfkey' id='12' label='PF12' width='2' />
</row>
<row>
- <button />
- <button action='move' target='cursor' direction='up' icon="go-up" />
- <button />
+ <button action='move' target='cursor' direction='up' icon="go-up" column='2' width='2' />
</row>
<row>
- <button action='move' target='cursor' direction='left' icon="go-back" />
- <button action="firstfield" icon="goto-top" />
- <button action='move' target='cursor' direction='right' icon="go-forward" />
+ <button action='move' target='cursor' direction='left' icon="go-back" width='2' />
+ <button action="firstfield" icon="goto-top" width='2' />
+ <button action='move' target='cursor' direction='right' icon="go-forward" width='2' />
</row>
<row>
- <button />
- <button action='move' target='cursor' direction='down' icon="go-down"/>
- <button />
+ <button action='move' target='cursor' direction='down' icon="go-down" column='2' width='2'/>
</row>
<row>
- <button action='pakey' id='1' label='PA1' />
- <button action='pakey' id='2' label='PA2' />
- <button action='pakey' id='3' label='PA3' />
+ <button action='pakey' id='1' label='PA1' width='2' />
+ <button action='pakey' id='2' label='PA2' width='2' />
+ <button action='pakey' id='3' label='PA3' width='2' />
</row>
<row>
- <button action='PreviousField' icon="goto-first" />
- <button action='NextField' icon="goto-last" />
+ <button action='PreviousField' icon="goto-first" width='3' />
+ <button action='NextField' icon="goto-last" width='3' />
</row>
<row>
- <button action='erase' target='all' label="Clear" />
- <button action='kybdreset' label="Reset" />
+ <button action='erase' target='all' label="Clear" width='3' />
+ <button action='kybdreset' label="Reset" width='3' />
</row>
- <row>
- <button action='EraseEOF' label="Erase\nEOF" />
- <button action='EraseInput' label="Erase\nInput" />
+ <row height='2'>
+ <button action='EraseEOF' label="Erase\nEOF" width='3' height='2'/>
+ <button action='EraseInput' label="Erase\nInput" width='3' height='2'/>
</row>
<row>
- <button action='Attn' label="Attn" />
- <button action='Break' label="Break" />
+ <button action='Attn' label="Attn" width='3' />
+ <button action='Break' label="Break" width='3' />
</row>
<row>
- <button action='Enter' icon="ok" />
+ <button action='Enter' icon="ok" width='6'/>
</row>
</keypad>