
/* Built with:
 gcc -o sample -g `pkg-config --cflags gtk+-2.0` sample.c `pkg-config --libs gtk+-2.0`
 */

#include <stdio.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>

#define MCOLS 4
#define MROWS 5

#define BUT_0     buttons[17]       /* 0 */
#define BUT_1     buttons[12]       /* 1 */
#define BUT_2     buttons[13]       /* 2 */
#define BUT_3     buttons[14]       /* 3 */
#define BUT_4     buttons[8]        /* 4 */
#define BUT_5     buttons[9]        /* 5 */
#define BUT_6     buttons[10]       /* 6 */
#define BUT_7     buttons[4]        /* 7 */
#define BUT_8     buttons[5]        /* 8 */
#define BUT_9     buttons[6]        /* 9 */
#define BUT_ADD   buttons[11]       /* + */
#define BUT_SUB   buttons[3]        /* - */
#define BUT_MUL   buttons[2]        /* x */
#define BUT_DIV   buttons[1]        /* / */
#define BUT_PNT   buttons[18]       /* . */
#define BUT_EQ    buttons[19]       /* = */

char *labels[MCOLS * MROWS] = {
    "NumLock", "/", "*", "-",
    "7",       "8", "9", " ",
    "4",       "5", "6", "+",
    "1",       "2", "3", " ", 
    " ",       "0", ".", "Enter"
};

int mods[MCOLS * MROWS] = {
    0, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0,
    0, 0, 0, 0
};

int values[MCOLS * MROWS] = {
    GDK_space, GDK_slash, GDK_asterisk, GDK_minus,
    GDK_7,     GDK_8,     GDK_9,        GDK_space,
    GDK_4,     GDK_5,     GDK_6,        GDK_plus,
    GDK_1,     GDK_2,     GDK_3,        GDK_space,
    GDK_space, GDK_0,     GDK_period,   GDK_equal
};

GtkAccelGroup *kbd_accel;
GtkWidget *buttons[MROWS * MCOLS];
GtkWidget *kframe;  

/*ARGSUSED*/
static void
button_proc(GtkButton *button, gpointer user_data)
{
    int n = (int) user_data;

    fprintf(stderr, "button_proc: n %d value %d\n", n, values[n]);
}


static void
create_kbd_accel(GtkWidget *button, guint button_mods, guint button_key) {
    gtk_widget_add_accelerator(button, "clicked", kbd_accel,
                               button_key, button_mods, GTK_ACCEL_VISIBLE);
}


static void
add_extra_kbd_accels()
{
    create_kbd_accel(BUT_0,   0, GDK_KP_0);
    create_kbd_accel(BUT_1,   0, GDK_KP_1);
    create_kbd_accel(BUT_2,   0, GDK_KP_2);
    create_kbd_accel(BUT_3,   0, GDK_KP_3);
    create_kbd_accel(BUT_4,   0, GDK_KP_4);
    create_kbd_accel(BUT_5,   0, GDK_KP_5);
    create_kbd_accel(BUT_6,   0, GDK_KP_6);
    create_kbd_accel(BUT_7,   0, GDK_KP_7);
    create_kbd_accel(BUT_8,   0, GDK_KP_8);
    create_kbd_accel(BUT_9,   0, GDK_KP_9);
    create_kbd_accel(BUT_ADD, 0, GDK_KP_Add);
    create_kbd_accel(BUT_SUB, 0, GDK_KP_Subtract);
    create_kbd_accel(BUT_MUL, 0, GDK_KP_Multiply);
    create_kbd_accel(BUT_DIV, 0, GDK_KP_Divide);
    create_kbd_accel(BUT_PNT, 0, GDK_KP_Delete);
    create_kbd_accel(BUT_EQ,  0, GDK_KP_Enter);
}

static void make_mtable(GtkWidget *frame, GtkWidget *vbox)
{
    int i, j, n;
    GtkWidget *table = gtk_table_new(MROWS, MCOLS, FALSE);

    gtk_widget_ref(table);
    gtk_widget_show(table);
    gtk_box_pack_start(GTK_BOX(vbox), table, TRUE, TRUE, 0);

    for (i = 0; i < MROWS; i++) {
        for (j = 0; j < MCOLS; j++) {
            n = i*MCOLS + j;
            fprintf(stderr, "n is %d\n", n);
            buttons[n] = gtk_button_new_with_label(labels[n]);
            gtk_widget_ref(buttons[n]);
            create_kbd_accel(buttons[n], mods[n], values[n]);
            gtk_widget_show(buttons[n]);
            g_signal_connect(G_OBJECT(buttons[n]), "clicked",
                             G_CALLBACK(button_proc), (gpointer) n);
            gtk_table_attach(GTK_TABLE(table), buttons[n],
                             j, j+1, i, i+1,
                             (GtkAttachOptions) (GTK_EXPAND | GTK_FILL),
                             (GtkAttachOptions) (GTK_EXPAND | GTK_FILL), 4, 4);
            gtk_widget_set_size_request(buttons[n], 60, 28);
        }
    }
}

void create_kframe()
{
    int i, k;
    GtkWidget *hbox, *vbox;

    kframe = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_policy(GTK_WINDOW(kframe), TRUE, TRUE, TRUE);
    vbox = gtk_vbox_new(FALSE, 0);
    gtk_widget_ref(vbox);
    gtk_widget_show(vbox);
    gtk_container_add(GTK_CONTAINER(kframe), vbox);
    make_mtable(kframe, vbox);
}

int main(int argc, char **argv)
{
    bindtextdomain("sample", "/usr/local/lib/locale");
    textdomain("sample");
    gtk_set_locale();
    gtk_init(&argc, &argv);
    kbd_accel = gtk_accel_group_new();
    create_kframe();
    add_extra_kbd_accels();
    gtk_window_add_accel_group(GTK_WINDOW(kframe), kbd_accel);
    gtk_widget_show(kframe);
    gtk_main();
}
