#include "main.h" #include "keyboard.h" enum { KEYBOARD_SIGNAL, LAST_SIGNAL }; static void keyboard_class_init (KeyboardClass *klass); static void keyboard_init (Keyboard *ttt); static guint keyboard_signals[LAST_SIGNAL] = { 0 }; GType keyboard_get_type(void) { static GType ttt_type = 0; if (!ttt_type) { static const GTypeInfo ttt_info = { sizeof (KeyboardClass), NULL, /* base_init */ NULL, /* base_finalize */ (GClassInitFunc)keyboard_class_init, NULL, /* class_finalize */ NULL, /* class_data */ sizeof(Keyboard), 0, (GInstanceInitFunc)keyboard_init, }; ttt_type = g_type_register_static (GTK_TYPE_TABLE, "Keyboard", &ttt_info, 0); } return ttt_type; } static void keyboard_class_init(KeyboardClass *klass) { keyboard_signals[KEYBOARD_SIGNAL] = g_signal_new("Keyboard", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION, G_STRUCT_OFFSET(KeyboardClass, Keyboard), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static gint keyboard_keyboard(GtkWidget *grab_widget, GdkEventKey *event, gpointer func_data) { Keyboard *local; gchar *tmp; if (event->type != GDK_KEY_PRESS) return FALSE; local = (Keyboard *)func_data; switch (event->keyval) { case GDK_1: case GDK_KP_1: g_signal_emit_by_name ((gpointer)local->button[0], "clicked", G_TYPE_NONE); return TRUE; case GDK_2: case GDK_KP_2: g_signal_emit_by_name ((gpointer)local->button[1], "clicked", G_TYPE_NONE); return TRUE; case GDK_3: case GDK_KP_3: g_signal_emit_by_name ((gpointer)local->button[2], "clicked", G_TYPE_NONE); return TRUE; case GDK_4: case GDK_KP_4: g_signal_emit_by_name ((gpointer)local->button[3], "clicked", G_TYPE_NONE); return TRUE; case GDK_5: case GDK_KP_5: g_signal_emit_by_name ((gpointer)local->button[4], "clicked", G_TYPE_NONE); return TRUE; case GDK_6: case GDK_KP_6: g_signal_emit_by_name ((gpointer)local->button[5], "clicked", G_TYPE_NONE); return TRUE; case GDK_7: case GDK_KP_7: g_signal_emit_by_name ((gpointer)local->button[6], "clicked", G_TYPE_NONE); return TRUE; case GDK_8: case GDK_KP_8: g_signal_emit_by_name ((gpointer)local->button[7], "clicked", G_TYPE_NONE); return TRUE; case GDK_9: case GDK_KP_9: g_signal_emit_by_name ((gpointer)local->button[8], "clicked", G_TYPE_NONE); return TRUE; case GDK_0: case GDK_KP_0: g_signal_emit_by_name ((gpointer)local->button[9], "clicked", G_TYPE_NONE); return TRUE; case GDK_BackSpace: g_signal_emit_by_name ((gpointer)local->button[10], "clicked", G_TYPE_NONE); return TRUE; case GDK_Q: case GDK_q: g_signal_emit_by_name ((gpointer)local->button[11], "clicked", G_TYPE_NONE); return TRUE; case GDK_W: case GDK_w: g_signal_emit_by_name ((gpointer)local->button[12], "clicked", G_TYPE_NONE); return TRUE; case GDK_E: case GDK_e: g_signal_emit_by_name ((gpointer)local->button[13], "clicked", G_TYPE_NONE); return TRUE; case GDK_R: case GDK_r: g_signal_emit_by_name ((gpointer)local->button[14], "clicked", G_TYPE_NONE); return TRUE; case GDK_T: case GDK_t: g_signal_emit_by_name ((gpointer)local->button[15], "clicked", G_TYPE_NONE); return TRUE; case GDK_Y: case GDK_y: g_signal_emit_by_name ((gpointer)local->button[16], "clicked", G_TYPE_NONE); return TRUE; case GDK_U: case GDK_u: g_signal_emit_by_name ((gpointer)local->button[17], "clicked", G_TYPE_NONE); return TRUE; case GDK_I: case GDK_i: g_signal_emit_by_name ((gpointer)local->button[18], "clicked", G_TYPE_NONE); return TRUE; case GDK_O: case GDK_o: g_signal_emit_by_name ((gpointer)local->button[19], "clicked", G_TYPE_NONE); return TRUE; case GDK_P: case GDK_p: g_signal_emit_by_name ((gpointer)local->button[20], "clicked", G_TYPE_NONE); return TRUE; case GDK_A: case GDK_a: g_signal_emit_by_name ((gpointer)local->button[21], "clicked", G_TYPE_NONE); return TRUE; case GDK_S: case GDK_s: g_signal_emit_by_name ((gpointer)local->button[22], "clicked", G_TYPE_NONE); return TRUE; case GDK_D: case GDK_d: g_signal_emit_by_name ((gpointer)local->button[23], "clicked", G_TYPE_NONE); return TRUE; case GDK_F: case GDK_f: g_signal_emit_by_name ((gpointer)local->button[24], "clicked", G_TYPE_NONE); return TRUE; case GDK_G: case GDK_g: g_signal_emit_by_name ((gpointer)local->button[25], "clicked", G_TYPE_NONE); return TRUE; case GDK_H: case GDK_h: g_signal_emit_by_name ((gpointer)local->button[26], "clicked", G_TYPE_NONE); return TRUE; case GDK_J: case GDK_j: g_signal_emit_by_name ((gpointer)local->button[27], "clicked", G_TYPE_NONE); return TRUE; case GDK_K: case GDK_k: g_signal_emit_by_name ((gpointer)local->button[28], "clicked", G_TYPE_NONE); return TRUE; case GDK_L: case GDK_l: g_signal_emit_by_name ((gpointer)local->button[29], "clicked", G_TYPE_NONE); return TRUE; case GDK_Return: case GDK_KP_Enter: g_signal_emit_by_name ((gpointer)local->button[30], "clicked", G_TYPE_NONE); return TRUE; case GDK_Z: case GDK_z: g_signal_emit_by_name ((gpointer)local->button[31], "clicked", G_TYPE_NONE); return TRUE; case GDK_X: case GDK_x: g_signal_emit_by_name ((gpointer)local->button[32], "clicked", G_TYPE_NONE); return TRUE; case GDK_C: case GDK_c: g_signal_emit_by_name ((gpointer)local->button[33], "clicked", G_TYPE_NONE); return TRUE; case GDK_V: case GDK_v: g_signal_emit_by_name ((gpointer)local->button[34], "clicked", G_TYPE_NONE); return TRUE; case GDK_B: case GDK_b: g_signal_emit_by_name ((gpointer)local->button[35], "clicked", G_TYPE_NONE); return TRUE; case GDK_N: case GDK_n: g_signal_emit_by_name ((gpointer)local->button[36], "clicked", G_TYPE_NONE); return TRUE; case GDK_M: case GDK_m: g_signal_emit_by_name ((gpointer)local->button[37], "clicked", G_TYPE_NONE); return TRUE; case GDK_period: case GDK_KP_Decimal: g_signal_emit_by_name ((gpointer)local->button[38], "clicked", G_TYPE_NONE); return TRUE; case GDK_space: g_signal_emit_by_name ((gpointer)local->button[39], "clicked", G_TYPE_NONE); return TRUE; } return FALSE; } static void keyboard_init(Keyboard *ttt) { GtkWidget *button; GtkWidget *label; PangoFontDescription *desc; const char *charset[] = {"1","2","3","4","5","6","7","8","9","0","Backspace", "Q","W","E","R","T","Y","U","I","O","P", "A","S","D","F","G","H","J","K","L","Enter", "Z","X","C","V","B","N","M",".", "Space",NULL}; gint i = 0, x = 0, y = 0; gtk_table_resize(GTK_TABLE(ttt), 48, 5); gtk_table_set_homogeneous(GTK_TABLE(ttt), FALSE); for(i=0;charset[i] != NULL;i++) { label = gtk_label_new(charset[i]); desc = pango_font_description_from_string("Monospace 17"); gtk_widget_modify_font(GTK_WIDGET(label), desc); pango_font_description_free(desc); ttt->button[i] = gtk_button_new(); gtk_container_add(GTK_CONTAINER(ttt->button[i]), label); gtk_widget_set_size_request(GTK_WIDGET(ttt->button[i]), -1, 64); if (x == 40 && y == 0) { /* We're at the Backspace key */ gtk_table_attach_defaults(GTK_TABLE(ttt), ttt->button[i], x, x+8, y, y+1); x = 1; y++; } else if (x == 37 && y == 1) { /* We're at the "P" key */ gtk_table_attach_defaults(GTK_TABLE(ttt), ttt->button[i], x, x+4, y, y+1); x = 2; y++; } else if (x == 38 && y == 2) { /* We're at the Enter Key */ gtk_table_attach_defaults(GTK_TABLE(ttt), ttt->button[i], x, x+8, y, y+1); x = 3; y++; } else if (x == 31 && y == 3) { /* We're at the "." key */ gtk_table_attach_defaults(GTK_TABLE(ttt), ttt->button[i], x, x+4, y, y+1); x = 11; y++; } else if (x == 11 && y == 4) { /* Space Bar */ gtk_table_attach_defaults(GTK_TABLE(ttt), ttt->button[i], x, x+28, y, y+1); } else { gtk_table_attach_defaults(GTK_TABLE(ttt), ttt->button[i], x, x+4, y, y+1); x += 4; } } } /* Deprecated */ GtkWidget *keyboard_new_with_entry() { return (GtkWidget *)NULL; } GtkWidget *keyboard_new_for_smart_entries(GtkWidget *entry) { GtkWidget *ret; guint keyboard_snoop; ret = GTK_WIDGET(g_object_new(keyboard_get_type(),NULL)); keyboard_snoop = gtk_key_snooper_install(keyboard_keyboard, (gpointer)ret); poslib_snoop_add(keyboard_snoop); return ret; } void keyboard_set_callback(GtkWidget *widget, GCallback(func)) { Keyboard *local; gint i = 0; const char *charset[] = {"1","2","3","4","5","6","7","8","9","0","Backspace", "Q","W","E","R","T","Y","U","I","O","P", "A","S","D","F","G","H","J","K","L","Enter", "Z","X","C","V","B","N","M",".", "Space",NULL}; local = (Keyboard *)widget; for (i=0;i<40;i++) { g_signal_connect(G_OBJECT(local->button[i]),"clicked", func,(gpointer)charset[i]); } return; } static gint keyboard_delete_error(gpointer data) { Keyboard *inner; inner = (Keyboard *)data; gtk_label_set_text(GTK_LABEL(inner->error), NULL); return FALSE; } void keyboard_set_error(GtkWidget *widget, const gchar *error) { gchar *buffer = NULL; Keyboard *local = NULL; local = (Keyboard *)widget; buffer = g_strdup_printf("%s",error); gtk_label_set_markup(GTK_LABEL(local->error), buffer); g_free(buffer); /*g_timeout_add(3000, keyboard_delete_error, widget);*/ return; } void keyboard_popup_cback(GtkWidget *widget, gpointer data) { gchar *func; func = g_object_get_data(G_OBJECT(widget),"func"); keyboard_popup((gchar *)data,func); return; } static void keyboard_popup_handle(GtkWidget *widget, gpointer data) { GtkWidget *smartentry; GtkWidget *toplevel; gchar *tmp = NULL, *current = NULL, *func = NULL; toplevel = gtk_widget_get_toplevel(widget); smartentry = smartentry_get_current(); if (smartentry == NULL) { g_warning("Assertion smartentry != NULL failed"); return; } current = gtk_entry_get_text(GTK_ENTRY(SMARTENTRY(smartentry)->entry)); if (!strcmp((gchar *)data,"Space")) { tmp = g_strdup_printf("%s ",current); } else if (!strcmp((gchar *)data,"Enter")) { tmp = g_strdup(smartentry_get_text("popup_data")); /* Good */ func = g_object_get_data(G_OBJECT(toplevel),"func"); poslib_func_call(func, tmp, NULL); if (GTK_WIDGET_TOPLEVEL(toplevel)) { smart_entries_free(); gtk_widget_destroy(GTK_WIDGET(toplevel)); } g_free(tmp); return; } else if (!strcmp((gchar *)data,"Backspace")) { tmp = g_strdup_printf("%s",current); tmp[strlen(tmp) - 1] = '\0'; } else { tmp = g_strdup_printf("%s%s",current,(gchar *)data); } gtk_entry_set_text(GTK_ENTRY(SMARTENTRY(smartentry)->entry), tmp); g_free(tmp); } static void keyboard_popup_close(GtkWidget *widget, gpointer data) { smart_entries_free(); gtk_widget_destroy(GTK_WIDGET((GtkWidget *)data)); return; } void keyboard_popup(const gchar *msg, const gchar *func) { GtkWidget *popwin, *label, *keyboard, *button, *vbox, *hbox, *keyalign, *hsep, *frame, *smartentry; PangoFontDescription *desc; popwin = gtk_window_new(GTK_WINDOW_TOPLEVEL); g_object_set_data(G_OBJECT(popwin),"func",(gpointer)func); gtk_window_set_decorated(GTK_WINDOW(popwin), FALSE); gtk_window_set_transient_for(GTK_WINDOW(popwin), GTK_WINDOW(window)); gtk_window_set_modal(GTK_WINDOW(popwin), TRUE); gtk_window_set_position(GTK_WINDOW(popwin), GTK_WIN_POS_CENTER_ALWAYS); gtk_widget_set_size_request(GTK_WIDGET(popwin), 1024, 600); vbox = gtk_vbox_new(FALSE,0); label = gtk_label_new(msg); desc = pango_font_description_from_string("Monospace 22"); gtk_widget_modify_font(label, desc); pango_font_description_free(desc); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); hsep = gtk_hseparator_new(); gtk_box_pack_start(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); keyalign = gtk_alignment_new(0.5,0,0,0); smartentry = smartentry_new_magic("popup_data", "Monospace 20", 300, -1); gtk_container_add(GTK_CONTAINER(keyalign),smartentry); gtk_box_pack_start(GTK_BOX(vbox), keyalign, FALSE, FALSE, 50); keyboard = keyboard_new_for_smart_entries(NULL); keyalign = gtk_alignment_new(0.5, 1, 1, 1); gtk_container_add(GTK_CONTAINER(keyalign), keyboard); gtk_box_pack_start(GTK_BOX(vbox), keyalign, FALSE, FALSE, 20); hbox = gtk_hbox_new(TRUE,0); gtk_widget_set_size_request(GTK_WIDGET(hbox), -1, 75); button = gtk_button_new(); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(keyboard_popup_close), (gpointer)popwin); label = gtk_label_new("Cancel"); desc = pango_font_description_from_string("Monospace 16"); gtk_widget_modify_font(label, desc); pango_font_description_free(desc); gtk_container_add(GTK_CONTAINER(button), label); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); button = gtk_button_new(); /* So this will work properly just as if they hit enter on the keypad */ g_object_set_data(G_OBJECT(button),"keyboard",(gpointer)keyboard); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(keyboard_popup_handle), (gchar *)"Enter"); label = gtk_label_new("Ok"); desc = pango_font_description_from_string("Monospace 16"); gtk_widget_modify_font(label, desc); pango_font_description_free(desc); gtk_container_add(GTK_CONTAINER(button), label); gtk_box_pack_end(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); hsep = gtk_hseparator_new(); gtk_box_pack_end(GTK_BOX(vbox), hsep, FALSE, FALSE, 0); frame = gtk_frame_new(NULL); gtk_container_add(GTK_CONTAINER(frame),vbox); gtk_container_add(GTK_CONTAINER(popwin),frame); keyboard_set_callback(keyboard, keyboard_popup_handle); gtk_widget_show_all(popwin); }