00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <stdio.h>
00033 #include <string.h>
00034
00035
00036 #include <X11/Xlib.h>
00037 #include <fakekey/fakekey.h>
00038
00039
00040 #include <gtk/gtk.h>
00041
00042
00043 #include "config.h"
00044 #include "ergtk-keyb.h"
00045
00046 #include "erkeyb-display-sched.h"
00047
00048
00049 #include "logging.h"
00050
00051
00052
00053
00054
00055
00056 #define NUM_COLUMNS 20
00057 #define NUM_ROWS 4
00058
00059 #define NUM_KEYS 32
00060 #define NUM_KEYS_FIRST_ROW 10
00061 #define NUM_KEYS_SECOND_ROW 9
00062 #define NUM_KEYS_THIRD_ROW 9
00063 #define NUM_KEYS_FOURTH_ROW 4
00064
00065 #define FIRST_ROW_START 0
00066 #define FIRST_ROW_END ( FIRST_ROW_START + NUM_KEYS_FIRST_ROW -1 )
00067 #define SECOND_ROW_START ( FIRST_ROW_END + 1 )
00068 #define SECOND_ROW_END ( SECOND_ROW_START + NUM_KEYS_SECOND_ROW -1 )
00069 #define THIRD_ROW_START ( SECOND_ROW_END + 1 )
00070 #define THIRD_ROW_END ( THIRD_ROW_START + NUM_KEYS_THIRD_ROW - 1 )
00071 #define FOURTH_ROW_START ( THIRD_ROW_END + 1 )
00072 #define FOURTH_ROW_END ( FOURTH_ROW_START + NUM_KEYS_FOURTH_ROW - 1 )
00073
00074
00075
00076
00077
00078 #define ERGTK_KEYB_GET_PRIVATE(o) \
00079 (G_TYPE_INSTANCE_GET_PRIVATE ((o), ERGTK_TYPE_KEYB, ErGtkKeybPrivate))
00080
00081
00082 G_DEFINE_TYPE (ErGtkKeyb, ergtk_keyb, GTK_TYPE_VBOX) ;
00083
00084
00085 typedef enum _key_alt key_alt;
00086
00087 enum _key_alt {
00088 KEY_ALT0 = 0,
00089 KEY_ALT0_SHIFTED = 1,
00090 KEY_ALT1 = 2,
00091 KEY_ALT1_SHIFTED = 3,
00092 KEY_ALT2 = 4,
00093 KEY_ALT2_SHIFTED = 5,
00094 KEY_ALT_MAX = 6
00095 };
00096
00097 typedef struct _rangetype rangetype;
00098
00099 struct _rangetype {
00100 int row;
00101 int column;
00102 int nrows;
00103 int ncolumns;
00104 } ;
00105
00106
00107
00108
00109
00110 typedef struct _c_keyboardmap c_keyboardmap;
00111
00112 struct _c_keyboardmap {
00113 int key_num;
00114 gchar* alt[6];
00115 };
00116
00117 typedef struct _charmap charmap;
00118
00119 struct _charmap {
00120 gint key_num;
00121 GList* alt;
00122 };
00123
00124 typedef enum _ergtk_keyfacetype ergtk_keyfacetype;
00125
00126 enum _ergtk_keyfacetype {
00127 ergtk_keyfacetype_label = 0,
00128 ergtk_keyfacetype_image,
00129 ergtk_keyfacetype_unknown = 255,
00130 };
00131
00132 typedef struct _ErGtkKey ErGtkKey;
00133
00134 struct _ErGtkKey {
00135 ErGtkKeyb* parent;
00136 gint key_num;
00137 GtkWidget* button;
00138 ergtk_keyfacetype key_facetype;
00139 union {
00140 GtkWidget* label;
00141 GtkWidget* image;
00142 } u;
00143 };
00144
00145 struct _ErGtkKeybPrivate
00146 {
00147 GString* xmlfile;
00148 charmap keymap[32];
00149 ErGtkKey keyboard[32];
00150 gint current_alt_keyb_num;
00151 gint num_alternatives;
00152 gboolean finalizing;
00153 guint highlight_id;
00154
00155
00156 Display* Xdpy;
00157 FakeKey* fk;
00158 GdkDisplay* Gdpy;
00159 };
00160
00161 enum {
00162 PROP_0,
00163 PROP_NUM_ALTERNATIVES,
00164 };
00165
00166
00167
00168
00169
00170
00171 static c_keyboardmap g_mykeymap[NUM_KEYS] =
00172 {
00173 { .key_num = 0, .alt = { "q", "Q", "1", "`", NULL, NULL, }, },
00174 { .key_num = 1, .alt = { "w", "W", "2", "'", NULL, NULL, }, },
00175 { .key_num = 2, .alt = { "e", "E", "3", "%", NULL, NULL, }, },
00176 { .key_num = 3, .alt = { "r", "R", "4", "^", NULL, NULL, }, },
00177 { .key_num = 4, .alt = { "t", "T", "5", "_", NULL, NULL, }, },
00178 { .key_num = 5, .alt = { "y", "Y", "6", "<", NULL, NULL, }, },
00179 { .key_num = 6, .alt = { "u", "U", "7", ">", NULL, NULL, }, },
00180 { .key_num = 7, .alt = { "i", "I", "8", "-", NULL, NULL, }, },
00181 { .key_num = 8, .alt = { "o", "O", "9", "+", NULL, NULL, }, },
00182 { .key_num = 9, .alt = { "p", "P", "0", "{", NULL, NULL, }, },
00183 { .key_num = 10, .alt = { "a", "A", "£", "}", NULL, NULL, }, },
00184 { .key_num = 11, .alt = { "s", "S", "=", "|", NULL, NULL, }, },
00185 { .key_num = 12, .alt = { "d", "D", "(", ";", NULL, NULL, }, },
00186 { .key_num = 13, .alt = { "f", "F", ")", "\"", NULL, NULL, }, },
00187 { .key_num = 14, .alt = { "g", "G", "\\", "\\", NULL, NULL, }, },
00188 { .key_num = 15, .alt = { "h", "H", "*", "*", NULL, NULL, }, },
00189 { .key_num = 16, .alt = { "j", "J", ":", ":", NULL, NULL, }, },
00190 { .key_num = 17, .alt = { "k", "K", ",", ",", NULL, NULL, }, },
00191 { .key_num = 18, .alt = { "l", "L", "/", "/", NULL, NULL, }, },
00192 { .key_num = 19, .alt = { "Shift", "Shift", "Shift", "Shift", "Shift", "Shift", }, },
00193 { .key_num = 20, .alt = { "z", "Z", "~", "~", NULL, NULL, }, },
00194 { .key_num = 21, .alt = { "x", "X", "@", "@", NULL, NULL, }, },
00195 { .key_num = 22, .alt = { "c", "C", "$", "€", NULL, NULL, }, },
00196 { .key_num = 23, .alt = { "v", "V", "&", "&", NULL, NULL, }, },
00197 { .key_num = 24, .alt = { "b", "B", "#", "#", NULL, NULL, }, },
00198 { .key_num = 25, .alt = { "n", "N", "!", "!", NULL, NULL, }, },
00199 { .key_num = 26, .alt = { "m", "M", "?", "?", NULL, NULL, }, },
00200 { .key_num = 27, .alt = { "Backspace", "Backspace", "Backspace", "Backspace", "Backspace", "Backspace", }, },
00201 { .key_num = 28, .alt = { "@123", "@123", "abc", "abc", "@123", "@123", }, },
00202 { .key_num = 29, .alt = { " ", " ", " ", " ", " ", " ", }, },
00203 { .key_num = 30, .alt = { ".", ".", ".", ".", ".", ".", }, },
00204 { .key_num = 31, .alt = { "Enter", "Enter", "Enter", "Enter", "Enter", "Enter", }, },
00205 };
00206
00207
00208
00209
00210
00211
00212 static void ergtk_keyb_class_init (ErGtkKeybClass* klass);
00213 static void ergtk_keyb_init (ErGtkKeyb* keyb);
00214 static void ergtk_keyb_finalize(GObject* object);
00215
00216 static void ergtk_keyb_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec );
00217 static void ergtk_keyb_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec );
00218
00219 static void ergtk_keyb_populate (ErGtkKeyb* keyb );
00220 static void ergtk_keyb_populate_real(ErGtkKeyb* keyb );
00221 static void ergtk_keyb_create_key_in_table(ErGtkKeyb* keyb, GtkWidget* table, char* keyname, int keyindex, rangetype range);
00222
00223 static gboolean ergtk_keyb_button_clicked_event_cb(GtkWidget* button, gpointer data);
00224 static gboolean on_highlight_expired( gpointer data );
00225
00226 static gint ergtk_keyb_send_key(ErGtkKeyb* keyb, char* keychar);
00227 static gint ergtk_keyb_send_keysym(ErGtkKeyb* keyb, KeySym keysym );
00228 static gint ergtk_keyb_redraw_keyboard(ErGtkKeyb* keyb);
00229 static int ergtk_keyb_init_fakekey(ErGtkKeyb* keyb);
00230 static void ergtk_keyb_string_free(gpointer data, gpointer user_data );
00231
00232
00233 static gboolean label_log_destroy ( GtkWidget* , gpointer );
00234 static gboolean image_log_destroy ( GtkWidget* , gpointer );
00235 static gboolean button_log_destroy ( GtkWidget* button, gpointer data );
00236
00237
00238
00239
00240
00241 static void ergtk_keyb_class_init (ErGtkKeybClass* klass)
00242 {
00243 DBG_ENTRY;
00244
00245 GObjectClass* object_class = G_OBJECT_CLASS(klass);
00246
00247 object_class->set_property = ergtk_keyb_set_property;
00248 object_class->get_property = ergtk_keyb_get_property;
00249
00250 object_class->finalize = ergtk_keyb_finalize;
00251
00252 g_object_class_install_property( object_class,
00253 PROP_NUM_ALTERNATIVES,
00254 g_param_spec_int (
00255 "num-alternatives",
00256 "Number of keyboard alternatives",
00257 "Specify the number of keyboard layout alternatives",
00258 0,
00259 6,
00260 4,
00261 G_PARAM_READWRITE ));
00262
00263
00264 g_type_class_add_private (klass, sizeof(ErGtkKeybPrivate));
00265
00266 DBG_EXIT;
00267 }
00268
00269 static void ergtk_keyb_init (ErGtkKeyb* keyb)
00270 {
00271 DBG_ENTRY;
00272
00273 ErGtkKeybPrivate* priv = keyb->priv;
00274 priv = keyb->priv = ERGTK_KEYB_GET_PRIVATE( keyb);
00275 priv->finalizing = FALSE;
00276 priv->highlight_id = 0;
00277 priv->xmlfile = NULL ;
00278
00279 memset(priv->keymap, 0x0, sizeof(priv->keymap));
00280
00281 int i = 0 ;
00282 for ( i = 0; i< NUM_KEYS; i++ )
00283 {
00284 int j = 0;
00285
00286 priv->keymap[i].key_num = g_mykeymap[i].key_num;
00287
00288 for ( j = 0; j<6; j++ )
00289 {
00290 if ( g_mykeymap[i].alt[j] != NULL )
00291 {
00292 GString* tmp = g_string_new( g_mykeymap[i].alt[j] );
00293 priv->keymap[i].alt = g_list_prepend(priv->keymap[i].alt, (gpointer) tmp);
00294 }
00295 }
00296 priv->keymap[i].alt = g_list_reverse(priv->keymap[i].alt);
00297 }
00298
00299 memset(priv->keyboard, 0x0, NUM_KEYS * sizeof(ErGtkKey));
00300 priv->current_alt_keyb_num = 0;
00301 priv->num_alternatives = 4;
00302 priv->Xdpy = NULL;
00303 priv->fk = NULL;
00304 priv->Gdpy = NULL;
00305
00306 ergtk_keyb_populate (keyb);
00307 ergtk_keyb_init_fakekey(keyb);
00308
00309 priv->Gdpy = gdk_display_get_default();
00310
00311 DBG_EXIT;
00312 }
00313
00314 GtkWidget* ergtk_keyb_new (void )
00315 {
00316 DBG_ENTRY;
00317
00318 ErGtkKeyb* result = NULL ;
00319
00320 result = g_object_new(ergtk_keyb_get_type(), "num-alternatives", 4, NULL ) ;
00321
00322 DBG_EXIT;
00323 return GTK_WIDGET( result );
00324 }
00325
00326 void ergtk_keyb_reset_keymap(ErGtkKeyb* thiz)
00327 {
00328 DBG_ENTRY;
00329
00330 ErGtkKeybPrivate* priv = thiz->priv;
00331
00332 DBG("Resetting alternate keymap 0.\n");
00333 priv->current_alt_keyb_num = 0 ;
00334 ergtk_keyb_redraw_keyboard(thiz);
00335
00336 DBG_EXIT;
00337 }
00338
00339 static void ergtk_keyb_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec )
00340 {
00341 ErGtkKeyb* keyb;
00342 ErGtkKeybPrivate* priv;
00343 gint num_alternatives;
00344
00345 keyb = ERGTK_KEYB(object);
00346 priv = keyb->priv;
00347
00348 switch (prop_id)
00349 {
00350 case PROP_NUM_ALTERNATIVES:
00351 num_alternatives = g_value_get_int(value);
00352 if ( priv->num_alternatives != num_alternatives )
00353 {
00354 priv->num_alternatives = num_alternatives;
00355 }
00356 break;
00357
00358 default:
00359 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
00360 break;
00361 }
00362 }
00363
00364 static void ergtk_keyb_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec )
00365 {
00366 ErGtkKeyb* keyb;
00367 ErGtkKeybPrivate* priv;
00368
00369 keyb = ERGTK_KEYB(object);
00370 priv = keyb->priv;
00371
00372 switch (prop_id)
00373 {
00374 case PROP_NUM_ALTERNATIVES:
00375 g_value_set_int(value, priv->num_alternatives);
00376 break;
00377
00378 default:
00379 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
00380 break;
00381 }
00382
00383 }
00384
00385 static void ergtk_keyb_string_free(gpointer data, gpointer user_data )
00386 {
00387 gboolean free_orig = *(gboolean*) user_data ;
00388 GString* to_delete = (GString*) data;
00389 gchar* orig = NULL ;
00390
00391 orig = g_string_free(to_delete, free_orig);
00392
00393 if ( free_orig == TRUE )
00394 {
00395 DBG_ASSERT( orig == NULL );
00396 }
00397 }
00398
00399 static void ergtk_keyb_finalize(GObject* object)
00400 {
00401 DBG_ENTRY;
00402 ErGtkKeyb* keyb = ERGTK_KEYB(object);
00403 ErGtkKeybPrivate* priv = keyb->priv;
00404 priv->finalizing = TRUE;
00405 if ( priv->highlight_id != 0 )
00406 {
00407 g_source_remove(priv->highlight_id);
00408 }
00409 priv->highlight_id = 0;
00410
00411 gchar* tmp = NULL;
00412 int i = 0 ;
00413
00414 if ( priv->xmlfile != NULL )
00415 {
00416 tmp = g_string_free(priv->xmlfile, TRUE);
00417 DBG_ASSERT(tmp == NULL ) ;
00418 }
00419
00420 for ( i = 0; i < NUM_KEYS; i++ )
00421 {
00422 if ( priv->keymap[i].alt != NULL )
00423 {
00424 gboolean weed_out = TRUE ;
00425 g_list_foreach( priv->keymap[i].alt, ergtk_keyb_string_free, (gpointer) &weed_out);
00426 g_list_free( priv->keymap[i].alt );
00427 priv->keymap[i].alt = NULL ;
00428 }
00429 }
00430
00431 for (i = 0; i < NUM_KEYS; i++ )
00432 {
00433 if ( priv->keyboard[i].parent != NULL )
00434 {
00435 priv->keyboard[i].parent = NULL ;
00436 }
00437 priv->keyboard[i].key_num = 0;
00438
00439 DBG_ASSERT( priv->keyboard[i].button == NULL ) ;
00440
00441 if ( priv->keyboard[i].key_facetype == ergtk_keyfacetype_label)
00442 {
00443 DBG_ASSERT( priv->keyboard[i].u.label == NULL ) ;
00444 ;
00445 }
00446 else if ( priv->keyboard[i].key_facetype == ergtk_keyfacetype_image)
00447 {
00448 DBG_ASSERT( priv->keyboard[i].u.image == NULL ) ;
00449 ;
00450 }
00451 }
00452 priv->current_alt_keyb_num = 0 ;
00453 priv->num_alternatives = 0 ;
00454 priv->fk = NULL ;
00455 XCloseDisplay( priv->Xdpy);
00456 priv->Xdpy = NULL ;
00457
00458 G_OBJECT_CLASS (ergtk_keyb_parent_class)->finalize(object);
00459
00460
00461 erkeyb_on_idle_display_yield(DM_HINT_FULL);
00462
00463 DBG_EXIT;
00464 }
00465
00466
00467 static void ergtk_keyb_populate (ErGtkKeyb* keyb )
00468 {
00469 DBG_ENTRY;
00470
00471 ErGtkKeybPrivate* priv = keyb->priv;
00472
00473 int i = 0;
00474 GList* ptr = NULL ;
00475 gchar* tmp = NULL ;
00476
00477 for ( i = 0; i < NUM_KEYS; i++ )
00478 {
00479
00480 priv->keyboard[i].parent = keyb;
00481
00482 priv->keyboard[i].key_num = i;
00483
00484 ptr = g_list_nth(priv->keymap[i].alt, 1);
00485 DBG_ASSERT(ptr != NULL ) ;
00486 tmp = ((GString*)(ptr->data))->str;
00487
00488 if (strcasecmp(tmp, "Shift") == 0)
00489 {
00490
00491 priv->keyboard[i].key_facetype = ergtk_keyfacetype_image ;
00492 }
00493 else if (strcasecmp(tmp, "Backspace") == 0)
00494 {
00495
00496 priv->keyboard[i].key_facetype = ergtk_keyfacetype_image ;
00497 }
00498 else
00499 {
00500 priv->keyboard[i].key_facetype = ergtk_keyfacetype_label ;
00501 }
00502 }
00503
00504
00505 ergtk_keyb_populate_real(keyb);
00506
00507 DBG_EXIT;
00508 }
00509
00510
00511 static void ergtk_keyb_populate_real(ErGtkKeyb* keyb )
00512 {
00513 DBG_ENTRY;
00514
00515 ErGtkKeybPrivate* priv = keyb->priv;
00516
00517 GtkWidget* table = gtk_table_new( NUM_ROWS, NUM_COLUMNS, TRUE );
00518 gtk_table_set_row_spacings(GTK_TABLE(table), 3 );
00519 gtk_table_set_col_spacings(GTK_TABLE(table), 3 );
00520
00521 {
00522 int i ;
00523
00524 for ( i = 0; i < NUM_ROWS; i++ )
00525 {
00526 switch (i)
00527 {
00528 case 0:
00529 {
00530 int j;
00531 int c;
00532
00533 for (j = 0, c = FIRST_ROW_START; c < SECOND_ROW_START ; j+=2, c++ )
00534 {
00535 rangetype range = {
00536 .row = i,
00537 .column = j,
00538 .nrows = 1,
00539 .ncolumns = 2
00540 };
00541 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00542 DBG_ASSERT( ptr != NULL ) ;
00543 gchar* keyname = ((GString*)(ptr->data))->str;
00544 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00545 }
00546 break;
00547 }
00548 case 1:
00549 {
00550 int j=0;
00551 int c;
00552
00553 for (j = 1, c = SECOND_ROW_START; c < THIRD_ROW_START ; j+=2, c++ )
00554 {
00555 rangetype range = {
00556 .row = i,
00557 .column = j,
00558 .nrows = 1,
00559 .ncolumns = 2
00560 };
00561 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00562 DBG_ASSERT( ptr != NULL ) ;
00563 gchar* keyname = ((GString*)(ptr->data))->str;
00564 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00565 }
00566 break;
00567 }
00568 case 2:
00569 {
00570 int j;
00571 int c;
00572
00573 for (j = 0, c = THIRD_ROW_START; c < FOURTH_ROW_START ; j+=2, c++ )
00574 {
00575 if ( c == THIRD_ROW_START )
00576 {
00577 rangetype range = {
00578 .row = i,
00579 .column = j,
00580 .nrows = 1,
00581 .ncolumns = 3
00582 };
00583 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00584 DBG_ASSERT( ptr != NULL ) ;
00585 gchar* keyname = ((GString*)(ptr->data))->str;
00586 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00587 j++;
00588 }
00589 else if ( c == THIRD_ROW_END )
00590 {
00591 rangetype range = {
00592 .row = i,
00593 .column = j,
00594 .nrows = 1,
00595 .ncolumns = 3
00596 };
00597 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00598 DBG_ASSERT( ptr != NULL ) ;
00599 gchar* keyname = ((GString*)(ptr->data))->str;
00600 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00601 }
00602 else {
00603 rangetype range = {
00604 .row = i,
00605 .column = j,
00606 .nrows = 1,
00607 .ncolumns = 2
00608 };
00609 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00610 DBG_ASSERT( ptr != NULL ) ;
00611 gchar* keyname = ((GString*)(ptr->data))->str;
00612 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00613 }
00614 }
00615 break;
00616 }
00617 case 3:
00618 {
00619 int j=0;
00620 int c;
00621
00622 for (c = FOURTH_ROW_START; c <= FOURTH_ROW_END ; c++ )
00623 {
00624 if ( j == 0 )
00625 {
00626 rangetype range = {
00627 .row = i,
00628 .column = j,
00629 .nrows = 1,
00630 .ncolumns = 4
00631 };
00632 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00633 DBG_ASSERT( ptr != NULL ) ;
00634 gchar* keyname = ((GString*)(ptr->data))->str;
00635 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00636 j+=4;
00637 continue;
00638 }
00639 if ( j == 4 )
00640 {
00641 rangetype range = {
00642 .row = i,
00643 .column = j,
00644 .nrows = 1,
00645 .ncolumns = 10
00646 };
00647 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00648 DBG_ASSERT( ptr != NULL ) ;
00649 gchar* keyname = ((GString*)(ptr->data))->str;
00650 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00651 j+=10;
00652 continue;
00653 }
00654 if ( j == 14 )
00655 {
00656 rangetype range = {
00657 .row = i,
00658 .column = j,
00659 .nrows = 1,
00660 .ncolumns = 2
00661 };
00662 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00663 DBG_ASSERT( ptr != NULL ) ;
00664 gchar* keyname = ((GString*)(ptr->data))->str;
00665 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00666 j+=2;
00667 continue;
00668 }
00669 if ( j== 16 )
00670 {
00671 rangetype range = {
00672 .row = i,
00673 .column = j,
00674 .nrows = 1,
00675 .ncolumns = 4
00676 };
00677 GList* ptr = g_list_nth(priv->keymap[c].alt, 0);
00678 DBG_ASSERT( ptr != NULL ) ;
00679 gchar* keyname = ((GString*)(ptr->data))->str;
00680 ergtk_keyb_create_key_in_table(keyb, table, (char*) keyname, c, range);
00681 j+=4;
00682 continue;
00683 }
00684 DBG_ASSERT( 0 );
00685 break;
00686 }
00687 break;
00688 }
00689 default:
00690 {
00691 DBG_ASSERT( 0 ) ;
00692 break;
00693 }
00694 }
00695 }
00696 }
00697 gtk_container_add(GTK_CONTAINER(keyb), table);
00698 gtk_widget_show(table);
00699
00700 DBG_EXIT;
00701 }
00702
00703 static void ergtk_keyb_create_key_in_table(ErGtkKeyb* keyb, GtkWidget* table, char* keyname, int keyindex, rangetype range)
00704 {
00705 GtkWidget* thekey = NULL;
00706 GtkWidget* thelabel = NULL;
00707 GtkWidget* theimage = NULL;
00708
00709 ErGtkKeybPrivate* priv = keyb->priv;
00710
00711 GList* ptr = g_list_nth(priv->keymap[keyindex].alt, 1);
00712 gchar* tmp = ((GString*)(ptr->data))->str;
00713
00714 priv->keyboard[keyindex].button = gtk_button_new();
00715
00716 g_signal_connect(
00717 GTK_OBJECT(priv->keyboard[keyindex].button),
00718 "destroy",
00719 GTK_SIGNAL_FUNC(gtk_widget_destroyed),
00720 (gpointer) &priv->keyboard[keyindex].button
00721 );
00722 g_signal_connect(
00723 GTK_OBJECT(priv->keyboard[keyindex].button),
00724 "destroy",
00725 GTK_SIGNAL_FUNC(button_log_destroy),
00726 (gpointer) NULL
00727 );
00728
00729 thekey = priv->keyboard[keyindex].button ;
00730 GTK_WIDGET_UNSET_FLAGS(thekey, GTK_CAN_FOCUS);
00731
00732
00733 if (priv->keyboard[keyindex].key_facetype == ergtk_keyfacetype_image )
00734 {
00735 if (strcasecmp(tmp, "Shift") == 0)
00736 {
00737 char path[512];
00738 snprintf(path, 512, "%s/%s", PKGDATADIR, "key-shift.png");
00739 priv->keyboard[keyindex].u.image = gtk_image_new_from_file((gchar*) path );
00740 }
00741 else if (strcasecmp(tmp, "Backspace") == 0)
00742 {
00743 char path[512];
00744 snprintf(path, 512, "%s/%s", PKGDATADIR, "key-backspace.png");
00745 priv->keyboard[keyindex].u.image = gtk_image_new_from_file((gchar*) path );
00746 }
00747 g_signal_connect(
00748 GTK_OBJECT(priv->keyboard[keyindex].u.image),
00749 "destroy",
00750 GTK_SIGNAL_FUNC(gtk_widget_destroyed),
00751 (gpointer) &priv->keyboard[keyindex].u.image
00752 );
00753 g_signal_connect(
00754 GTK_OBJECT(priv->keyboard[keyindex].u.image),
00755 "destroy",
00756 GTK_SIGNAL_FUNC(image_log_destroy),
00757 (gpointer) NULL
00758 );
00759
00760 theimage = priv->keyboard[keyindex].u.image;
00761 gtk_container_add(GTK_CONTAINER(thekey), theimage);
00762 gtk_widget_show(theimage);
00763 }
00764 else
00765 {
00766 if ( keyname != NULL )
00767 {
00768 priv->keyboard[keyindex].u.label = gtk_label_new(keyname);
00769 gtk_widget_set_sensitive(priv->keyboard[keyindex].button, TRUE);
00770 }
00771 else
00772 {
00773 priv->keyboard[keyindex].u.label = gtk_label_new(" ");
00774
00775
00776 gtk_widget_set_sensitive(priv->keyboard[keyindex].button, TRUE);
00777 }
00778 g_signal_connect(
00779 GTK_OBJECT(priv->keyboard[keyindex].u.label),
00780 "destroy",
00781 GTK_SIGNAL_FUNC(gtk_widget_destroyed),
00782 (gpointer) &priv->keyboard[keyindex].u.label
00783 );
00784 g_signal_connect(
00785 GTK_OBJECT(priv->keyboard[keyindex].u.label),
00786 "destroy",
00787 GTK_SIGNAL_FUNC(label_log_destroy),
00788 (gpointer) NULL
00789 );
00790
00791 thelabel = priv->keyboard[keyindex].u.label ;
00792 gtk_container_add(GTK_CONTAINER(thekey), thelabel);
00793 gtk_widget_show(thelabel);
00794 }
00795
00796 g_signal_connect(GTK_OBJECT(thekey), "clicked", G_CALLBACK(ergtk_keyb_button_clicked_event_cb), (gpointer) &priv->keyboard[keyindex]);
00797
00798 gtk_widget_set_size_request(thekey, 35, 35) ;
00799 gtk_table_attach(GTK_TABLE(table), thekey, range.column, (range.column+range.ncolumns),
00800 range.row, (range.row+range.nrows), GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0, 0);
00801
00802 gtk_widget_show(thekey);
00803
00804 return;
00805 }
00806
00807
00808 static gboolean on_highlight_expired( gpointer data )
00809 {
00810 DBG_ENTRY;
00811
00812 GtkWidget* button = (GtkWidget*) data ;
00813 GtkWidget* label = gtk_bin_get_child(GTK_BIN(button));
00814
00815 GdkColor black;
00816 gdk_color_parse("black", &black);
00817 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &black);
00818 gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &black);
00819 GdkColor white;
00820 gdk_color_parse("white", &white);
00821 gtk_widget_modify_bg(button, GTK_STATE_NORMAL, &white);
00822 gtk_widget_modify_bg(button, GTK_STATE_ACTIVE, &white);
00823 gtk_widget_queue_draw(button);
00824
00825 erkeyb_on_idle_display_yield(DM_HINT_KEY);
00826
00827 DBG_EXIT;
00828 return FALSE;
00829 }
00830
00831 static gboolean ergtk_keyb_button_clicked_event_cb(GtkWidget* button, gpointer data)
00832 {
00833 DBG_ENTRY;
00834
00835 DBG_ASSERT ( data != NULL ) ;
00836 DBG_ASSERT ( button != NULL );
00837
00838 ErGtkKey* key = (ErGtkKey*) data;
00839 ErGtkKeyb* keyb = key->parent;
00840 ErGtkKeybPrivate* priv = keyb->priv;
00841 GtkWidget* label = gtk_bin_get_child(GTK_BIN(button));
00842
00843 GList* ptr = NULL ;
00844 gchar* keychar = NULL ;
00845
00846 gint display_update_hint = DM_HINT_KEY;
00847
00848 erkeyb_stop_display_update();
00849
00850 GdkColor white;
00851 gdk_color_parse("white", &white);
00852 gtk_widget_modify_fg(label, GTK_STATE_NORMAL, &white);
00853 gtk_widget_modify_fg(label, GTK_STATE_ACTIVE, &white);
00854 GdkColor black;
00855 gdk_color_parse("black", &black);
00856 gtk_widget_modify_bg(button, GTK_STATE_NORMAL, &black);
00857 gtk_widget_modify_bg(button, GTK_STATE_ACTIVE, &black);
00858 gtk_widget_queue_draw(button);
00859
00860 ptr = g_list_nth(priv->keymap[key->key_num].alt, priv->current_alt_keyb_num);
00861
00862 if ( ptr == NULL )
00863 {
00864 DBG("Key has no value!\n");
00865 goto cb_exit;
00866 }
00867
00868
00869
00870 keychar = ((GString*)(ptr->data))->str;
00871 DBG_ASSERT(keychar != NULL );
00872 DBG_ASSERT(priv->current_alt_keyb_num < KEY_ALT_MAX ) ;
00873
00874 if ( priv->current_alt_keyb_num % 2 == 1 )
00875 {
00876 if (strcasecmp (keychar, "Shift") == 0)
00877 {
00878 DBG("Shift key pressed\n");
00879 priv->current_alt_keyb_num -- ;
00880 DBG_ASSERT(priv->current_alt_keyb_num >= KEY_ALT0 ) ;
00881 ergtk_keyb_redraw_keyboard(keyb);
00882 display_update_hint = DM_HINT_PARTIAL;
00883 goto cb_exit;
00884 }
00885 if ((strcasecmp (keychar, "@123") == 0) || (strcasecmp (keychar, "abc") == 0))
00886 {
00887 DBG("Switch to alternate keyboard layout key pressed \n");
00888 priv->current_alt_keyb_num += 1;
00889 DBG_ASSERT( priv->current_alt_keyb_num % 2 == 0);
00890 DBG_ASSERT( priv->num_alternatives < KEY_ALT_MAX );
00891 priv->current_alt_keyb_num %= priv->num_alternatives;
00892 ergtk_keyb_redraw_keyboard(keyb);
00893 display_update_hint = DM_HINT_PARTIAL;
00894 goto cb_exit;
00895 }
00896 if (strcasecmp(keychar, "Enter") == 0 )
00897 {
00898 DBG("Return key pressed\n");
00899 ergtk_keyb_send_keysym(keyb, XK_Return);
00900 priv->current_alt_keyb_num --;
00901 DBG_ASSERT(priv->current_alt_keyb_num >= KEY_ALT0 ) ;
00902 ergtk_keyb_redraw_keyboard(keyb);
00903 display_update_hint = DM_HINT_PARTIAL;
00904 goto cb_exit;
00905 }
00906 if (strcasecmp (keychar, "Backspace") == 0)
00907 {
00908 DBG("Backspace pressed\n");
00909 ergtk_keyb_send_keysym(keyb, XK_BackSpace);
00910 priv->current_alt_keyb_num --;
00911 DBG_ASSERT(priv->current_alt_keyb_num >= KEY_ALT0 ) ;
00912 ergtk_keyb_redraw_keyboard(keyb);
00913 display_update_hint = DM_HINT_PARTIAL;
00914 goto cb_exit;
00915 }
00916
00917 DBG("(Normal) Pressed key %s\n", (char*) keychar );
00918 ergtk_keyb_send_key(keyb, keychar);
00919 priv->current_alt_keyb_num -- ;
00920 DBG_ASSERT(priv->current_alt_keyb_num >= KEY_ALT0 ) ;
00921 ergtk_keyb_redraw_keyboard(keyb);
00922 display_update_hint = DM_HINT_PARTIAL;
00923 goto cb_exit;
00924 }
00925
00926
00927 if (strcasecmp (keychar, "Shift") == 0)
00928 {
00929 DBG("Shift key pressed\n");
00930 DBG_ASSERT(priv->current_alt_keyb_num % 2 == 0 ) ;
00931 priv->current_alt_keyb_num ++ ;
00932 ergtk_keyb_redraw_keyboard(keyb);
00933 display_update_hint = DM_HINT_PARTIAL;
00934 goto cb_exit;
00935 }
00936 if ((strcasecmp (keychar, "@123") == 0) || (strcasecmp (keychar, "abc") == 0))
00937 {
00938 DBG("Switch to alternate keyboard layout key pressed \n");
00939 DBG_ASSERT( priv->current_alt_keyb_num % 2 == 0);
00940 DBG_ASSERT( priv->num_alternatives < KEY_ALT_MAX );
00941 priv->current_alt_keyb_num += 2 ;
00942 priv->current_alt_keyb_num %= priv->num_alternatives;
00943 ergtk_keyb_redraw_keyboard(keyb);
00944 display_update_hint = DM_HINT_PARTIAL;
00945 goto cb_exit;
00946 }
00947 if (strcasecmp (keychar, "Backspace") == 0)
00948 {
00949 DBG("Backspace pressed\n");
00950 ergtk_keyb_send_keysym(keyb, XK_BackSpace);
00951 display_update_hint = DM_HINT_KEY;
00952 goto cb_exit;
00953 }
00954 if (strcasecmp(keychar, "Enter") == 0 )
00955 {
00956 DBG("Return key pressed\n");
00957 ergtk_keyb_send_keysym(keyb, XK_Return);
00958 display_update_hint = DM_HINT_KEY;
00959 goto cb_exit;
00960 }
00961
00962 DBG("(Normal) Pressed key %s\n", (char*) keychar );
00963 ergtk_keyb_send_key(keyb, keychar);
00964 display_update_hint = DM_HINT_KEY;
00965
00966 cb_exit:
00967 gtk_widget_queue_draw(button);
00968 gdk_display_flush(priv->Gdpy);
00969 gdk_display_sync(priv->Gdpy);
00970
00971 erkeyb_on_timeout_display_update(50, display_update_hint);
00972
00973
00974 priv->highlight_id = g_timeout_add(200, on_highlight_expired, (gpointer) button );
00975
00976 DBG_EXIT;
00977 return FALSE;
00978 }
00979
00980 static gint ergtk_keyb_redraw_keyboard(ErGtkKeyb* keyb)
00981 {
00982 DBG_ENTRY;
00983
00984 GList* ptr = NULL ;
00985 gchar* tmp = NULL ;
00986
00987 ErGtkKeybPrivate* priv = keyb->priv;
00988
00989 int i = 0;
00990
00991 for (i=0; i < NUM_KEYS; i++ )
00992 {
00993
00994 ptr = g_list_nth( priv->keymap[i].alt, priv->current_alt_keyb_num);
00995
00996 if ( NULL != ptr )
00997 {
00998 tmp = ((GString*)(ptr->data))->str;
00999 }
01000 else
01001 {
01002 tmp = NULL ;
01003 }
01004
01005 switch (i)
01006 {
01007 case 19:
01008 case 27:
01009
01010 break;
01011 default:
01012 if ( tmp != NULL ) {
01013 gtk_label_set_label(GTK_LABEL(priv->keyboard[i].u.label), (const gchar*) tmp);
01014 gtk_widget_set_sensitive(priv->keyboard[i].button, TRUE);
01015 }
01016 else {
01017 gtk_label_set_label(GTK_LABEL(priv->keyboard[i].u.label), (const gchar*) " ");
01018
01019
01020 gtk_widget_set_sensitive(priv->keyboard[i].button, TRUE);
01021 }
01022 break;
01023 }
01024 }
01025
01026 DBG_EXIT;
01027 return FALSE ;
01028 }
01029
01030 static gint ergtk_keyb_send_key(ErGtkKeyb* keyb, char* keychar)
01031 {
01032 DBG_ENTRY;
01033
01034 ErGtkKeybPrivate* priv = keyb->priv;
01035
01036 DBG_ASSERT( priv->fk != NULL );
01037
01038 fakekey_press(priv->fk, (const unsigned char*) keychar, -1 , 0);
01039 fakekey_release(priv->fk);
01040
01041 DBG_EXIT;
01042 return 1;
01043 }
01044
01045 static gint ergtk_keyb_send_keysym(ErGtkKeyb* keyb, KeySym keysym )
01046 {
01047 DBG_ENTRY;
01048
01049 ErGtkKeybPrivate* priv = keyb->priv;
01050
01051 DBG_ASSERT( priv->fk != NULL );
01052
01053 fakekey_press_keysym(priv->fk, keysym, 0 );
01054 fakekey_release(priv->fk);
01055
01056 DBG_EXIT;
01057 return 1;
01058 }
01059
01060 static int ergtk_keyb_init_fakekey(ErGtkKeyb* keyb)
01061 {
01062 ErGtkKeybPrivate* priv = keyb->priv;
01063
01064 priv->Xdpy = XOpenDisplay(getenv("DISPLAY"));
01065
01066 if (priv->Xdpy == NULL)
01067 {
01068 ERR("Could not open X display\n");
01069 DBG_EXIT;
01070 return 0;
01071 }
01072
01073 priv->fk = fakekey_init(priv->Xdpy);
01074
01075 if ( priv->fk == NULL)
01076 {
01077 ERR("Could not initialize fakekey\n");
01078 DBG_EXIT;
01079 return 0;
01080 }
01081
01082 DBG("fakekey initialized\n");
01083 return 1;
01084
01085 }
01086
01087 static gboolean label_log_destroy ( GtkWidget* label, gpointer data )
01088 {
01089 DBG("-- LABEL destroyed.\n");
01090 return FALSE;
01091 }
01092
01093 static gboolean image_log_destroy ( GtkWidget* image, gpointer data )
01094 {
01095 DBG("-- IMAGE destroyed.\n");
01096 return FALSE;
01097 }
01098
01099 static gboolean button_log_destroy ( GtkWidget* button, gpointer data )
01100 {
01101 DBG("-- BUTTON destroyed.\n");
01102 return FALSE;
01103 }