Browse Source

Remove gtk1 support, add (mostly working) gtk3 support.

Default is still gtk2.

Gtk3 seems to require quite a lot more memory (twice what is used by
gtk2 ?!?). It also feels a lot slower.
master
Kim Woelders 9 years ago
parent
commit
6b2567ba8f
  1. 6
      Makefile.am
  2. 42
      configure.ac
  3. 38
      e16keyedit.h
  4. 129
      ipc.c
  5. 5
      ipc.h
  6. 26
      menus.c
  7. 6
      menus.h
  8. 616
      viewer.c
  9. 4
      viewer.h

6
Makefile.am

@ -2,8 +2,8 @@ AUTOMAKE_OPTIONS=foreign
bin_PROGRAMS = e16keyedit
e16keyedit_SOURCES = ipc.c ipc.h menus.c menus.h viewer.c viewer.h
e16keyedit_SOURCES = ipc.c menus.c viewer.c e16keyedit.h
CPPFLAGS = -D DATADIR=\"$(datadir)\"
CPPFLAGS = -D DATADIR=\"$(datadir)\" $(GTK_CFLAGS)
LDADD = $(X_LIBS) -lX11
LDADD = $(GTK_LIBS) $(X_LIBS) -lX11

42
configure.ac

@ -14,27 +14,31 @@ AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
PKG_PROG_PKG_CONFIG
dnl Checks for libraries.
AC_ARG_ENABLE(gtk2,
[AC_HELP_STRING([--enable-gtk2],[enable gtk2 GUI (instead of GTK1) [default=yes]])],,
[enable_gtk2=yes])
if test "x$enable_gtk2" = "xyes" ; then
pkg_modules="gtk+-2.0 >= 2.0.0"
PKG_CHECK_MODULES(PACKAGE, [$pkg_modules])
CFLAGS="$CFLAGS $PACKAGE_CFLAGS"
LIBS="$LIBS $PACKAGE_LIBS"
AC_DEFINE(ENABLE_GTK2, , [Define to enable gtk2 support])
else
if ! gtk-config --version &> /dev/null ; then
AC_MSG_ERROR([Gtk+ is required.])
else
CFLAGS="$CFLAGS `gtk-config --cflags`"
LIBS="$LIBS `gtk-config --libs`"
fi
fi
AC_ARG_WITH(gtk,
[ --with-gtk Select GTK version to use (auto/gtk2/gtk3) @<:@default=auto@:>@],,
with_gtk=auto)
test_gtk="$with_gtk"
if test "x$with_gtk" = "xauto" ; then test_gtk="gtk2"; fi
if test "x$test_gtk" = "xgtk2" ; then
AC_MSG_CHECKING([for GTK2]);
pkg_modules="gtk+-2.0 >= 2.0.0"
PKG_CHECK_MODULES(GTK, [$pkg_modules],,
[if test "x$with_gtk" = "xauto" ; then test_gtk="gtk3"; fi])
AC_SUBST(ENABLE_GTK2)
fi
if test "x$test_gtk" = "xgtk3" ; then
AC_MSG_CHECKING([for GTK3]);
pkg_modules="gtk+-3.0 >= 3.0.0"
PKG_CHECK_MODULES(GTK, [$pkg_modules])
fi
if test "x$GTK_CFLAGS" = "x" ; then
AC_MSG_ERROR([GTK 2 or 3 is required.])
fi
dnl Checks for header files.
AC_PATH_X

38
e16keyedit.h

@ -0,0 +1,38 @@
#ifndef _E16KEYEDIT_H_
#define _E16KEYEDIT_H_
#if __GNUC__ /* FIXME - Use autofoo */
#define __UNUSED__ __attribute__((unused))
#else
#define __UNUSED__
#endif
#if GTK_CHECK_VERSION(3,0,0)
#define USE_GTK 3
#define gtk_hbox_new(homogeneous, spacing) \
gtk_box_new(GTK_ORIENTATION_HORIZONTAL, spacing)
#define gtk_vbox_new(homogeneous, spacing) \
gtk_box_new(GTK_ORIENTATION_VERTICAL, spacing)
#else
#define USE_GTK 2
#endif
/* ipc.c */
extern gint CommsInit(void (*msg_receive_func) (gchar * msg));
extern void CommsSend(const gchar * s);
/* menus.c */
extern GtkWidget *CreateBarSubMenu(GtkWidget * menu, const char *szName);
extern GtkWidget *CreateRightAlignBarSubMenu(GtkWidget * menu,
const char *szName);
extern GtkWidget *CreateMenuItem(GtkWidget * menu, const char *szName,
const char *szAccel, const char *szTip,
GCallback func, const void *data);
/* viewer.c */
extern GtkAccelGroup *accel_group;
void on_exit_application(void);
#endif /* _E16KEYEDIT_H_ */

129
ipc.c

@ -8,8 +8,11 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "ipc.h"
#include "viewer.h"
#include "e16keyedit.h"
#define gdk_window_foreign_new(xwin) \
gdk_x11_window_foreign_new_for_display(gdk_display_get_default(), xwin)
typedef struct _client
{
@ -41,8 +44,8 @@ static Window CommsFindCommsWindow(void);
static gchar *CommsGet(Client ** c, XEvent * ev);
static Client *MakeClient(Window win);
static void ListFreeClient(void *ptr);
extern gchar in_init;
extern gint gdk_error_warnings;
static gchar in_init = 0;
static gint gdk_error_warnings;
gint
CommsInit(void (*msg_receive_func) (gchar * msg))
@ -53,6 +56,9 @@ CommsInit(void (*msg_receive_func) (gchar * msg))
CommsSetup();
comms_win = win = CommsFindCommsWindow();
if (win == None)
return 1;
cl = MakeClient(win);
g_snprintf(st, sizeof(st), "%8x", (int)win);
cl->name = g_strdup(st);
@ -61,10 +67,10 @@ CommsInit(void (*msg_receive_func) (gchar * msg))
gdk_window_add_filter(gdkwin, CommsFilter, NULL);
gdkwin2 = gdk_window_foreign_new(my_win);
gdk_window_add_filter(gdkwin2, CommsFilter, NULL);
XSelectInput(GDK_DISPLAY(), win,
StructureNotifyMask | SubstructureNotifyMask);
gdk_window_set_events(gdkwin, GDK_STRUCTURE_MASK);
msg_receive_callback = msg_receive_func;
return 1;
return 0;
}
void
@ -80,8 +86,10 @@ CommsSend(const gchar * s)
if ((!s) || (!c))
return;
len = strlen(s);
if (!a)
a = XInternAtom(GDK_DISPLAY(), "ENL_MSG", True);
a = gdk_x11_get_xatom_by_name("ENL_MSG");
ev.xclient.type = ClientMessage;
ev.xclient.serial = 0;
ev.xclient.send_event = True;
@ -101,13 +109,15 @@ CommsSend(const gchar * s)
ss[20] = 0;
for (k = 0; k < 20; k++)
ev.xclient.data.b[k] = ss[k];
XSendEvent(GDK_DISPLAY(), c->win, False, 0, (XEvent *) & ev);
XSendEvent(gdk_x11_get_default_xdisplay(), c->win, False, 0,
(XEvent *) & ev);
}
return;
XFlush(gdk_x11_get_default_xdisplay());
}
static GdkFilterReturn
CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event __UNUSED__,
gpointer data __UNUSED__)
{
XEvent *xevent;
gchar *msg = NULL;
@ -117,7 +127,8 @@ CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
data = NULL;
if (!a)
a = XInternAtom(GDK_DISPLAY(), "ENL_MSG", True);
a = gdk_x11_get_xatom_by_name("ENL_MSG");
xevent = (XEvent *) gdk_xevent;
switch (xevent->type)
{
@ -140,12 +151,10 @@ CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
g_snprintf(st, sizeof(st), "%8x", (int)comms_win);
e_client->name = g_strdup(st);
if (gdkwin)
gdk_window_unref(gdkwin);
g_object_unref(gdkwin);
gdkwin = gdk_window_foreign_new(comms_win);
gdk_window_add_filter(gdkwin, CommsFilter, NULL);
XSelectInput(GDK_DISPLAY(), comms_win,
StructureNotifyMask |
SubstructureNotifyMask);
gdk_window_set_events(gdkwin, GDK_STRUCTURE_MASK);
}
sleep(1);
}
@ -155,12 +164,8 @@ CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
GtkWidget *win, *label, *align, *frame, *button,
*vbox;
#ifdef ENABLE_GTK2
win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
#else
win = gtk_window_new(GTK_WINDOW_DIALOG);
#endif
gtk_window_set_policy(GTK_WINDOW(win), 0, 0, 1);
gtk_window_set_resizable(GTK_WINDOW(win), FALSE);
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_CENTER);
frame = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
@ -168,9 +173,8 @@ CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
gtk_container_set_border_width(GTK_CONTAINER(align), 32);
vbox = gtk_vbox_new(FALSE, 5);
button = gtk_button_new_with_label("Bye bye!");
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(on_exit_application),
NULL);
g_signal_connect(G_OBJECT(button), "clicked",
on_exit_application, NULL);
label =
gtk_label_new("EEEEEEEEEEEEEEK! HELP! HEEEEEEEEEELP!\n"
"\n" "Enlightenemnt dissapeared on me!\n"
@ -192,10 +196,12 @@ CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
}
else
{
#if USE_GTK == 0 /* Needed? */
gdk_window_destroy_notify(((GdkEventAny *) event)->window);
#endif
}
return GDK_FILTER_REMOVE;
break;
case ClientMessage:
if (xevent->xclient.message_type != a)
return GDK_FILTER_CONTINUE;
@ -205,11 +211,11 @@ CommsFilter(GdkXEvent * gdk_xevent, GdkEvent * event, gpointer data)
if (msg_receive_callback)
(*msg_receive_callback) (msg);
g_free(msg);
return GDK_FILTER_REMOVE;
}
break;
default:
return GDK_FILTER_REMOVE;
break;
}
return GDK_FILTER_REMOVE;
}
@ -222,7 +228,7 @@ CommsSetup(void)
str = getenv("ENL_WM_ROOT");
root_win = (str) ? strtoul(str, NULL, 0) : GDK_ROOT_WINDOW();
my_win = XCreateSimpleWindow(GDK_DISPLAY(), root_win,
my_win = XCreateSimpleWindow(gdk_x11_get_default_xdisplay(), root_win,
-100, -100, 5, 5, 0, 0, 0);
}
@ -238,12 +244,13 @@ CommsFindCommsWindow(void)
int dint;
unsigned int duint;
a = XInternAtom(GDK_DISPLAY(), "ENLIGHTENMENT_COMMS", True);
a = gdk_x11_get_xatom_by_name("ENLIGHTENMENT_COMMS");
if (a != None)
{
s = NULL;
XGetWindowProperty(GDK_DISPLAY(), root_win, a, 0, 14, False,
AnyPropertyType, &ar, &format, &num, &after, &s);
XGetWindowProperty(gdk_x11_get_default_xdisplay(), root_win, a, 0, 14,
False, AnyPropertyType, &ar, &format, &num, &after,
&s);
if (s)
{
sscanf((char *)s, "%*s %x", (unsigned int *)&win);
@ -255,17 +262,18 @@ CommsFindCommsWindow(void)
p = gdk_error_warnings;
gdk_error_warnings = 0;
if (!XGetGeometry(GDK_DISPLAY(), win, &rt, &dint, &dint,
&duint, &duint, &duint, &duint))
if (!XGetGeometry
(gdk_x11_get_default_xdisplay(), win, &rt, &dint, &dint,
&duint, &duint, &duint, &duint))
win = 0;
gdk_flush();
gdk_error_warnings = p;
s = NULL;
if (win)
{
XGetWindowProperty(GDK_DISPLAY(), win, a, 0, 14, False,
AnyPropertyType, &ar, &format, &num,
&after, &s);
XGetWindowProperty(gdk_x11_get_default_xdisplay(), win, a, 0,
14, False, AnyPropertyType, &ar, &format,
&num, &after, &s);
if (s)
XFree(s);
else
@ -286,7 +294,8 @@ CommsGet(Client ** c, XEvent * ev)
static Atom a;
if (!a)
a = XInternAtom(GDK_DISPLAY(), "ENL_MSG", True);
a = gdk_x11_get_xatom_by_name("ENL_MSG");
if ((!ev) || (!c))
return (NULL);
if (ev->type != ClientMessage)
@ -334,20 +343,10 @@ MakeClient(Window win)
{
Client *c;
c = g_malloc(sizeof(Client));
if (!c)
return (NULL);
c->name = NULL;
c->win = win;
c->msg = NULL;
c->clientname = NULL;
c->version = NULL;
c->author = NULL;
c->email = NULL;
c->web = NULL;
c->address = NULL;
c->info = NULL;
return (c);
c = g_malloc0(sizeof(Client));
if (c)
c->win = win;
return c;
}
static void
@ -358,24 +357,14 @@ ListFreeClient(void *ptr)
c = (Client *) ptr;
if (!c)
return;
if (c->name)
g_free(c->name);
if (c->msg)
g_free(c->msg);
if (c->clientname)
g_free(c->clientname);
if (c->version)
g_free(c->version);
if (c->author)
g_free(c->author);
if (c->email)
g_free(c->email);
if (c->web)
g_free(c->web);
if (c->address)
g_free(c->address);
if (c->info)
g_free(c->info);
g_free(c->name);
g_free(c->msg);
g_free(c->clientname);
g_free(c->version);
g_free(c->author);
g_free(c->email);
g_free(c->web);
g_free(c->address);
g_free(c->info);
g_free(c);
return;
}

5
ipc.h

@ -1,5 +0,0 @@
gint CommsInit(void (*msg_receive_func) (gchar * msg));
void CommsSend(const gchar * s);
gchar in_init;
gint gdk_error_warnings;

26
menus.c

@ -8,8 +8,7 @@
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "menus.h"
#include "viewer.h"
#include "e16keyedit.h"
GtkWidget *
CreateBarSubMenu(GtkWidget * menu, const char *szName)
@ -18,13 +17,12 @@ CreateBarSubMenu(GtkWidget * menu, const char *szName)
GtkWidget *submenu;
menuitem = gtk_menu_item_new_with_label(szName);
gtk_menu_bar_append(GTK_MENU_BAR(menu), menuitem);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);
submenu = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
return submenu;
}
GtkWidget *
@ -34,19 +32,20 @@ CreateRightAlignBarSubMenu(GtkWidget * menu, const char *szName)
GtkWidget *submenu;
menuitem = gtk_menu_item_new_with_label(szName);
#if USE_GTK == 2
gtk_menu_item_right_justify(GTK_MENU_ITEM(menuitem));
gtk_menu_bar_append(GTK_MENU_BAR(menu), menuitem);
#endif
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);
submenu = gtk_menu_new();
gtk_menu_item_set_submenu(GTK_MENU_ITEM(menuitem), submenu);
return submenu;
}
GtkWidget *
CreateMenuItem(GtkWidget * menu, const char *szName, const char *szAccel,
const char *szTip, GtkSignalFunc func, const void *data)
const char *szTip, GCallback func, const void *data)
{
GtkWidget *menuitem;
@ -54,15 +53,15 @@ CreateMenuItem(GtkWidget * menu, const char *szName, const char *szAccel,
{
menuitem = gtk_menu_item_new_with_label(szName);
if (func)
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(func), (gpointer) data);
g_signal_connect(G_OBJECT(menuitem), "activate", func,
(gpointer) data);
}
else
{
menuitem = gtk_menu_item_new();
}
gtk_menu_append(GTK_MENU(menu), menuitem);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
gtk_widget_show(menuitem);
if (szAccel && szAccel[0] == '^')
@ -72,11 +71,8 @@ CreateMenuItem(GtkWidget * menu, const char *szName, const char *szAccel,
GTK_ACCEL_VISIBLE);
}
if (szTip && strlen(szTip))
{
gtk_tooltips_set_tip(tooltips, menuitem, szTip, NULL);
}
if (szTip && *szTip)
gtk_widget_set_tooltip_text(menuitem, szTip);
return menuitem;
}

6
menus.h

@ -1,6 +0,0 @@
GtkWidget *CreateBarSubMenu(GtkWidget * menu, const char *szName);
GtkWidget *CreateRightAlignBarSubMenu(GtkWidget * menu,
const char *szName);
GtkWidget *CreateMenuItem(GtkWidget * menu, const char *szName,
const char *szAccel, const char *szTip,
GtkSignalFunc func, const void *data);

616
viewer.c

@ -2,6 +2,7 @@
#include <gtk/gtk.h>
#include <ctype.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -11,22 +12,22 @@
#include <gdk/gdkx.h>
#include <unistd.h>
#include "viewer.h"
#include "menus.h"
#include "ipc.h"
#include "e16keyedit.h"
#if __GNUC__ /* FIXME - Use autofoo */
#define __UNUSED__ __attribute__((unused))
#if USE_GTK == 3
#define USE_GTK_TREEVIEW 1
#else
#define __UNUSED__
#define USE_GTK_TREEVIEW 1
#endif
#if !USE_GTK_TREEVIEW
#define ENABLE_SORTING 1
#endif
#define DEBUG 0
#define VER(maj, min, mic) (10000 * (maj) + 100 * (min) + (mic))
extern GtkTooltips *tooltips;
extern GtkAccelGroup *accel_group;
GtkAccelGroup *accel_group;
static GtkWidget *clist;
static GtkWidget *act_key;
@ -219,13 +220,68 @@ mod_short_to_index(const char *name_short)
return 0; /* Discard modifier */
}
#if USE_GTK_TREEVIEW
static int
clist_sel_row_get(GtkTreeSelection * sel)
{
int row, *rows;
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreePath *path;
row = -1;
if (gtk_tree_selection_get_selected(sel, &model, &iter))
{
path = gtk_tree_model_get_path(model, &iter);
rows = gtk_tree_path_get_indices(path);
row = rows[0];
}
return row;
}
#endif
static void
clist_row_current_set_value(GtkWidget * widget, int col, const char *txt)
{
#if USE_GTK_TREEVIEW
GtkTreeSelection *sel;
GtkTreeModel *model;
GtkTreeIter iter;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
if (gtk_tree_selection_get_selected(sel, &model, &iter))
gtk_list_store_set(GTK_LIST_STORE(model), &iter, col, txt, -1);
#else
gtk_clist_set_text(GTK_CLIST(widget), last_row, col, txt);
#endif
}
static void
clist_row_moveto(GtkWidget * widget, int row)
{
#if USE_GTK_TREEVIEW
GtkTreeSelection *sel;
GtkTreePath *path;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
path = gtk_tree_path_new_from_indices(row, -1);
gtk_tree_selection_select_path(sel, path);
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(widget), path, NULL, FALSE, .5,
.5);
gtk_tree_path_free(path);
#else
gtk_clist_select_row(GTK_CLIST(widget), row, 0);
gtk_clist_moveto(GTK_CLIST(widget), row, 0, 0.5, 0.5);
#endif
}
static void
e_cb_key_change(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
{
GtkWidget *win, *label, *frame, *align;
win = gtk_window_new(GTK_WINDOW_POPUP);
gtk_window_set_policy(GTK_WINDOW(win), 0, 0, 1);
gtk_window_set_position(GTK_WINDOW(win), GTK_WIN_POS_MOUSE);
frame = gtk_frame_new(NULL);
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
@ -248,72 +304,96 @@ e_cb_key_change(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
char *key;
XEvent ev;
gdk_window_set_events(win->window, GDK_KEY_PRESS_MASK);
XSetInputFocus(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(win->window),
#define WIDGET_XID(widget) GDK_WINDOW_XID(gtk_widget_get_window(widget))
gdk_window_set_events(gtk_widget_get_window(win), GDK_KEY_PRESS_MASK);
XGrabKeyboard(gdk_x11_get_default_xdisplay(), WIDGET_XID(win),
False, GrabModeAsync, GrabModeAsync, CurrentTime);
XSetInputFocus(gdk_x11_get_default_xdisplay(), WIDGET_XID(win),
RevertToPointerRoot, CurrentTime);
gdk_keyboard_grab(win->window, TRUE, CurrentTime);
XWindowEvent(GDK_DISPLAY(), GDK_WINDOW_XWINDOW(win->window),
XWindowEvent(gdk_x11_get_default_xdisplay(), WIDGET_XID(win),
KeyPressMask, &ev);
#ifdef ENABLE_GTK2
gdk_keyboard_ungrab(GDK_CURRENT_TIME);
#else
gdk_keyboard_ungrab(gdk_time_get());
#endif
key = XKeysymToString(XkbKeycodeToKeysym(GDK_DISPLAY(),
ev.xkey.keycode, 0, 0));
XUngrabKeyboard(gdk_x11_get_default_xdisplay(), CurrentTime);
key = XKeysymToString(XkbKeycodeToKeysym(gdk_x11_get_default_xdisplay(),
ev.xkey.keycode, 0, 0));
gtk_entry_set_text(GTK_ENTRY(act_key), key);
gtk_clist_set_text(GTK_CLIST(clist), last_row, 1, key);
clist_row_current_set_value(clist, 1, key);
}
gtk_widget_destroy(win);
}
static void
e_cb_modifier(GtkWidget * widget __UNUSED__, gpointer data)
e_cb_modifier(GtkWidget * widget, gpointer data __UNUSED__)
{
gint value;
int i;
value = (gint) (glong) data;
gtk_clist_set_text(GTK_CLIST(clist), last_row, 0, MOD_TEXT(value));
if (dont_update)
return;
i = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
clist_row_current_set_value(clist, 0, MOD_TEXT(i));
}
static gchar *
wait_for_ipc_msg(void)
{
gtk_main();
e_ipc_msg = NULL;
do
{
gtk_main_iteration();
}
while (!e_ipc_msg);
return e_ipc_msg;
}
#if USE_GTK_TREEVIEW
static void
change_action(GtkTreeSelection * sel, gpointer data __UNUSED__)
#else
static void
change_action(GtkWidget * my_clist __UNUSED__, gint row, gint column __UNUSED__,
GdkEventButton * event __UNUSED__, gpointer data __UNUSED__)
#endif
{
int k;
if (dont_update)
return;
#if USE_GTK_TREEVIEW
int row;
row = clist_sel_row_get(sel);
#endif
if (row < 0)
return;
k = action_row_to_index[row];
if (actions[k].param_tpe != 0)
{
gtk_entry_set_editable(GTK_ENTRY(act_params), TRUE);
gtk_editable_set_editable(GTK_EDITABLE(act_params), TRUE);
gtk_widget_set_sensitive(act_params, TRUE);
}
else
{
gtk_entry_set_editable(GTK_ENTRY(act_params), FALSE);
gtk_editable_set_editable(GTK_EDITABLE(act_params), FALSE);
gtk_widget_set_sensitive(act_params, FALSE);
gtk_entry_set_text(GTK_ENTRY(act_params), "");
}
dont_update = 1;
if (actions[k].command)
gtk_entry_set_text(GTK_ENTRY(act_params), actions[k].command);
else
gtk_entry_set_text(GTK_ENTRY(act_params), "* Not available *");
gtk_clist_set_text(GTK_CLIST(clist), last_row, 2, actions[k].text);
gtk_clist_set_text(GTK_CLIST(clist), last_row, 3,
gtk_entry_get_text(GTK_ENTRY(act_params)));
dont_update = 0;
clist_row_current_set_value(clist, 2, actions[k].text);
clist_row_current_set_value(clist, 3,
gtk_entry_get_text(GTK_ENTRY(act_params)));
}
static char *
@ -335,23 +415,39 @@ dupcat(char *dst, const char *src)
}
static void
on_save_data(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
on_save_data(void)
{
char *buf = NULL;
int i;
buf = dupcat(buf, "ac kb set\nAclass KEYBINDINGS global\n");
#if USE_GTK_TREEVIEW
GtkTreeModel *model;
GtkTreeIter iter;
gboolean ok;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(clist));
for (ok = gtk_tree_model_get_iter_first(model, &iter); ok;
ok = gtk_tree_model_iter_next(model, &iter))
#else
int i;
for (i = 0; i < real_rows; i++)
#endif
{
char tmp[1024];
char *params;
char *key;
char *mod;
char *mod, *key, *prm;
int modifier = 0;
int j;
#if USE_GTK_TREEVIEW
gtk_tree_model_get(model, &iter, 0, &mod, 1, &key, 3, &prm, -1);
#else
gtk_clist_get_text(GTK_CLIST(clist), i, 0, &mod);
gtk_clist_get_text(GTK_CLIST(clist), i, 1, &key);
gtk_clist_get_text(GTK_CLIST(clist), i, 3, &prm);
#endif
for (j = 0; j < 21; j++)
{
if (!strcmp(MOD_TEXT(j), mod))
@ -359,11 +455,8 @@ on_save_data(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
modifier = j;
}
}
gtk_clist_get_text(GTK_CLIST(clist), i, 1, &key);
gtk_clist_get_text(GTK_CLIST(clist), i, 3, &params);
snprintf(tmp, sizeof(tmp), "%s %s %s %s\n", "KeyDown",
modifiers[modifier].name_short, key, params);
modifiers[modifier].name_short, key, prm);
buf = dupcat(buf, tmp);
}
@ -377,57 +470,80 @@ on_save_data(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
free(buf);
}
#if USE_GTK_TREEVIEW
static void
selection_made(GtkTreeSelection * sel, gpointer data __UNUSED__)
#else
static void
selection_made(GtkWidget * my_clist __UNUSED__, gint row,
gint column __UNUSED__, GdkEventButton * event __UNUSED__,
gpointer data __UNUSED__)
#endif
{
gchar *modstring;
gchar *keyused;
gchar *actperform;
gchar *paramsused;
gchar *mod, *key, *act, *prm;
int i;
#if USE_GTK_TREEVIEW
int row;
row = clist_sel_row_get(sel);
#endif
if (row < 0)
return;
dont_update = 1;
gtk_clist_get_text(GTK_CLIST(clist), row, 0, &modstring);
gtk_option_menu_set_history(GTK_OPTION_MENU(act_mod), 0);
for (i = 1; i < 21; i++)
#if USE_GTK_TREEVIEW
GtkTreeIter iter;
GtkTreeModel *model;
if (gtk_tree_selection_get_selected(sel, &model, &iter))
{
if (!strcmp(MOD_TEXT(i), modstring))
{
gtk_option_menu_set_history(GTK_OPTION_MENU(act_mod), i);
}
gtk_tree_model_get(model, &iter,
0, &mod, 1, &key, 2, &act, 3, &prm, -1);
}
#else
gtk_clist_get_text(GTK_CLIST(clist), row, 0, &mod);
gtk_clist_get_text(GTK_CLIST(clist), row, 1, &key);
gtk_clist_get_text(GTK_CLIST(clist), row, 2, &act);
gtk_clist_get_text(GTK_CLIST(clist), row, 3, &prm);
#endif
gtk_clist_get_text(GTK_CLIST(clist), row, 1, &keyused);
gtk_entry_set_text(GTK_ENTRY(act_key), keyused);
gtk_clist_get_text(GTK_CLIST(clist), row, 2, &actperform);
gtk_clist_get_text(GTK_CLIST(clist), row, 3, &paramsused);
gtk_entry_set_text(GTK_ENTRY(act_params), paramsused);
for (i = 0; i < 21; i++)
{
if (!strcmp(MOD_TEXT(i), mod))
gtk_combo_box_set_active(GTK_COMBO_BOX(act_mod), i);
}
gtk_entry_set_text(GTK_ENTRY(act_key), key);
gtk_entry_set_text(GTK_ENTRY(act_params), prm);
i = match_action_by_selection(actperform);
i = match_action_by_selection(act);
if (i < 0 || actions[i].param_tpe == 0)
{
gtk_entry_set_editable(GTK_ENTRY(act_params), FALSE);
gtk_editable_set_editable(GTK_EDITABLE(act_params), FALSE);
gtk_widget_set_sensitive(act_params, FALSE);
}
else
{
gtk_entry_set_editable(GTK_ENTRY(act_params), TRUE);
gtk_editable_set_editable(GTK_EDITABLE(act_params), TRUE);
gtk_widget_set_sensitive(act_params, TRUE);
}
#if USE_GTK_TREEVIEW
g_free(mod);
g_free(key);
g_free(act);
g_free(prm);
#endif
if (i >= 0)
{
i = action_index_to_row[i];
gtk_clist_select_row(GTK_CLIST(act_clist), i, 0);
gtk_clist_moveto(GTK_CLIST(act_clist), i, 0, 0.5, 0.5);
clist_row_moveto(act_clist, i);
}
/* printf("%s\n%s\n%s\n%s\n",modstring,keyused,actperform,paramsused); */
/* printf("%s\n%s\n%s\n%s\n",mod,key,act,prm); */
last_row = row;
@ -469,6 +585,7 @@ get_line(gchar * str, int num)
}
}
#if ENABLE_SORTING
static void
on_resort_columns(GtkWidget * widget __UNUSED__, gint column,
gpointer data __UNUSED__)
@ -499,70 +616,79 @@ on_resort_columns(GtkWidget * widget __UNUSED__, gint column,
gtk_clist_sort(GTK_CLIST(clist));
}
#endif /* ENABLE_SORTING */
static void
on_delete_row(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
{
#if USE_GTK_TREEVIEW
GtkTreeSelection *sel;
GtkTreeIter iter;
GtkTreeModel *model;
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(clist));
if (!gtk_tree_selection_get_selected(sel, &model, &iter))
return;
gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
#else
gtk_clist_remove(GTK_CLIST(clist), last_row);
#endif
real_rows--;
if (last_row >= real_rows)
last_row--;
gtk_clist_select_row(GTK_CLIST(clist), last_row, 0);
gtk_clist_moveto(GTK_CLIST(clist), last_row, 0, 0.5, 0.5);
clist_row_moveto(clist, last_row);
}
static void
on_create_row(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
{
#if USE_GTK_TREEVIEW
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_tree_view_get_model(GTK_TREE_VIEW(clist));
gtk_list_store_append(GTK_LIST_STORE(model), &iter);
gtk_list_store_set(GTK_LIST_STORE(model), &iter,
0, "", 1, "", 2, "", 3, "", -1);
#else
char *stuff[4];
stuff[0] = malloc(2);
strcpy(stuff[0], "");
stuff[1] = malloc(2);
strcpy(stuff[1], "");
stuff[2] = malloc(2);
strcpy(stuff[2], "");
stuff[3] = malloc(2);
strcpy(stuff[3], "");
stuff[0] = "";
stuff[1] = "";
stuff[2] = "";
stuff[3] = "";
gtk_clist_select_row(GTK_CLIST(clist),
gtk_clist_append(GTK_CLIST(clist), stuff), 0);
if (stuff[0])
free(stuff[0]);
if (stuff[1])
free(stuff[1]);
if (stuff[2])
free(stuff[2]);
if (stuff[3])
free(stuff[3]);
#endif
last_row = real_rows++;
gtk_clist_select_row(GTK_CLIST(clist), last_row, 0);
gtk_clist_moveto(GTK_CLIST(clist), last_row, 0, 0.5, 0.5);
clist_row_moveto(clist, last_row);
}
static void
on_change_params(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
on_change_params(GtkWidget * widget, gpointer data __UNUSED__)
{
if (!dont_update)
{
gtk_clist_set_text(GTK_CLIST(clist), last_row, 3,
gtk_entry_get_text(GTK_ENTRY(act_params)));
}
const char *txt;
if (dont_update)
return;
txt = gtk_entry_get_text(GTK_ENTRY(widget));
clist_row_current_set_value(clist, 3, txt);
}
void
on_exit_application(GtkWidget * widget __UNUSED__, gpointer data __UNUSED__)
on_exit_application(void)
{
gtk_exit(0);
exit(0);
}
static void
on_save_and_exit_application(GtkWidget * widget, gpointer data)
on_save_and_exit_application(void)
{
on_save_data(widget, data);
on_exit_application(widget, data);
on_save_data();
on_exit_application();
}
static GtkWidget *
@ -582,75 +708,99 @@ create_list_window(void)
GtkWidget *entry;
GtkWidget *button;
GtkWidget *hbox;
GtkWidget *m, *mi, *om;
GtkWidget *menu, *menuitem;
GtkWidget *om;
GtkWidget *menu;
#if USE_GTK_TREEVIEW
GtkCellRenderer *renderer;
GtkListStore *store;
GtkTreeIter iter;
GtkTreeSelection *sel;
#endif
int i;
list_window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(list_window), 400, 400);
gtk_object_set_data(GTK_OBJECT(list_window), "key_editor", list_window);
GTK_WIDGET_SET_FLAGS(list_window, GTK_CAN_FOCUS);
GTK_WIDGET_SET_FLAGS(list_window, GTK_CAN_DEFAULT);
g_object_set_data(G_OBJECT(list_window), "key_editor", list_window);
gtk_widget_set_can_focus(list_window, TRUE);
gtk_widget_set_can_default(list_window, TRUE);
gtk_window_set_title(GTK_WINDOW(list_window), "E Keys Editor");
bigvbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(bigvbox);
gtk_container_add(GTK_CONTAINER(list_window), bigvbox);
menubar = gtk_menu_bar_new();
gtk_widget_show(menubar);
gtk_box_pack_start(GTK_BOX(bigvbox), menubar, FALSE, FALSE, 0);
menu = CreateBarSubMenu(menubar, "File");
menuitem = CreateMenuItem(menu, "Save", "", "Save Current Data", NULL,
"save data");
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(on_save_data), NULL);
menuitem = CreateMenuItem(menu, "Save & Quit", "",
"Save Current Data & Quit Application", NULL,
"save quit");
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(on_save_and_exit_application), NULL);
menuitem =
CreateMenuItem(menu, "Quit", "", "Quit Without Saving", NULL,
"quit program");
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(on_exit_application), NULL);
CreateMenuItem(menu, "Save", "", "Save Current Data", on_save_data, NULL);
CreateMenuItem(menu, "Save & Quit", "",
"Save Current Data & Quit Application",
on_save_and_exit_application, NULL);
CreateMenuItem(menu, "Quit", "", "Quit Without Saving",
on_exit_application, NULL);
#if 0 /* Not implemented */
menu = CreateRightAlignBarSubMenu(menubar, "Help");
menuitem = CreateMenuItem(menu, "About", "", "About E Keybinding Editor",
NULL, "about");
menuitem = CreateMenuItem(menu, "Documentation", "",
"Read the Keybinding Editor Documentation", NULL,
"read docs");
#endif
#if USE_GTK == 3
panes = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
#else
panes = gtk_hpaned_new();
gtk_widget_show(panes);
gtk_paned_set_gutter_size(GTK_PANED(panes), 10);
#endif
gtk_box_pack_start(GTK_BOX(bigvbox), panes, TRUE, TRUE, 0);
scrollybit = gtk_scrolled_window_new(NULL, NULL);
gtk_widget_show(scrollybit);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollybit),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
gtk_paned_pack1(GTK_PANED(panes), scrollybit, TRUE, FALSE);
#if USE_GTK_TREEVIEW
clist = gtk_tree_view_new();
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(clist),
-1, "Modifier", renderer, "text",
0, NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(clist),
-1, "Key", renderer, "text", 1,
NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(clist),
-1, "Action to Perform",
renderer, "text", 2, NULL);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(clist),
-1, "Command", renderer, "text",
3, NULL);
store = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
G_TYPE_STRING);
#else
clist = gtk_clist_new(4);
gtk_widget_show(clist);
gtk_container_add(GTK_CONTAINER(scrollybit), clist);
gtk_clist_set_column_title(GTK_CLIST(clist), 0, "Modifier");
gtk_clist_set_column_title(GTK_CLIST(clist), 1, "Key");
gtk_clist_set_column_title(GTK_CLIST(clist), 2, "Action to Perform");
gtk_clist_set_column_title(GTK_CLIST(clist), 3, "Command");
#if 0
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 0, TRUE);
gtk_clist_set_column_auto_resize(GTK_CLIST(clist), 1, TRUE);
#endif
gtk_clist_column_titles_show(GTK_CLIST(clist));
gtk_signal_connect(GTK_OBJECT(clist), "select_row",
GTK_SIGNAL_FUNC(selection_made), NULL);
gtk_signal_connect(GTK_OBJECT(clist), "click_column",
GTK_SIGNAL_FUNC(on_resort_columns), NULL);
#endif
gtk_container_add(GTK_CONTAINER(scrollybit), clist);
{
char *msg, *buf;
int i, j, k, modifier;
int j, k, modifier;
char event[128], mod[128], key[128], *params;
const char *stuff[4];
int len;
@ -691,7 +841,14 @@ create_list_window(void)
stuff[1] = key;
stuff[2] = (k >= 0) ? actions[k].text : "* Not recognised *";
stuff[3] = params;
#if USE_GTK_TREEVIEW
gtk_list_store_append(store, &iter);
gtk_list_store_set(store, &iter,
0, stuff[0], 1, stuff[1],
2, stuff[2], 3, stuff[3], -1);
#else
gtk_clist_append(GTK_CLIST(clist), (char **)stuff);
#endif
real_rows++;
next:
@ -699,118 +856,152 @@ create_list_window(void)
}
g_free(msg);
}
#if USE_GTK_TREEVIEW
gtk_tree_view_set_model(GTK_TREE_VIEW(clist), GTK_TREE_MODEL(store));
g_object_unref(store);
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(clist));
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(selection_made), NULL);
#if ENABLE_SORTING
g_signal_connect(G_OBJECT(clist), "click_column", /////////////////// CRAP
G_CALLBACK(on_resort_columns), NULL);
#endif
#else
gtk_clist_columns_autosize(GTK_CLIST(clist));
g_signal_connect(G_OBJECT(clist), "select_row",
G_CALLBACK(selection_made), NULL);
g_signal_connect(G_OBJECT(clist), "click_column",
G_CALLBACK(on_resort_columns), NULL);
#endif
vbox = gtk_vbox_new(FALSE, 0);
gtk_widget_show(vbox);
frames = gtk_frame_new("Edit Keybinding Properties");
gtk_container_set_border_width(GTK_CONTAINER(frames), 2);
gtk_widget_show(frames);
gtk_paned_pack2(GTK_PANED(panes), vbox, FALSE, TRUE);
gtk_paned_pack2(GTK_PANED(panes), vbox, FALSE, FALSE);
gtk_box_pack_start(GTK_BOX(vbox), frames, TRUE, TRUE, 0);
frame_vbox = gtk_vbox_new(FALSE, 3);
gtk_widget_show(frame_vbox);
gtk_container_set_border_width(GTK_CONTAINER(frame_vbox), 4);
gtk_container_add(GTK_CONTAINER(frames), frame_vbox);
#if USE_GTK == 3
table = gtk_grid_new();
gtk_grid_set_row_spacing(GTK_GRID(table), 3);
gtk_grid_set_column_spacing(GTK_GRID(table), 3);
#else
table = gtk_table_new(3, 3, FALSE);
gtk_widget_show(table);
gtk_table_set_row_spacings(GTK_TABLE(table), 3);
gtk_table_set_col_spacings(GTK_TABLE(table), 3);
#endif
gtk_box_pack_start(GTK_BOX(frame_vbox), table, FALSE, FALSE, 2);
alignment = gtk_alignment_new(1.0, 0.5, 0, 0);
label = gtk_label_new("Key:");
gtk_container_add(GTK_CONTAINER(alignment), label);
gtk_widget_show(alignment);
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(label);
#if USE_GTK == 3
gtk_widget_set_hexpand(alignment, GTK_FILL);
gtk_grid_attach(GTK_GRID(table), alignment, 0, 0, 1, 1);
#else
gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 0, 1,
GTK_FILL, (GtkAttachOptions) (0), 0, 0);
#endif
alignment = gtk_alignment_new(1.0, 0.5, 0, 0);
label = gtk_label_new("Modifier:");
gtk_container_add(GTK_CONTAINER(alignment), label);
gtk_widget_show(alignment);
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(label);
#if USE_GTK == 3
gtk_widget_set_hexpand(alignment, GTK_FILL);
gtk_grid_attach(GTK_GRID(table), alignment, 0, 1, 1, 1);
#else
gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 1, 2,
GTK_FILL, (GtkAttachOptions) (0), 0, 0);
#endif
alignment = gtk_alignment_new(1.0, 0.5, 0, 0);
label = gtk_label_new("Command:");
gtk_container_add(GTK_CONTAINER(alignment), label);
gtk_widget_show(alignment);
gtk_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT);
gtk_widget_show(label);
#if USE_GTK == 3
gtk_widget_set_hexpand(alignment, GTK_FILL);
gtk_grid_attach(GTK_GRID(table), alignment, 0, 2, 1, 1);
#else
gtk_table_attach(GTK_TABLE(table), alignment, 0, 1, 2, 3,
GTK_FILL, (GtkAttachOptions) (0), 0, 0);
#endif
act_key = entry = gtk_entry_new_with_max_length(4096);
gtk_widget_show(entry);
act_key = entry = gtk_entry_new();
gtk_entry_set_max_length(GTK_ENTRY(entry), 4096);
gtk_widget_set_sensitive(entry, FALSE);
/* gtk_widget_set_usize(entry, 24, -1); */
#if USE_GTK == 3
gtk_widget_set_hexpand(entry, GTK_EXPAND | GTK_FILL);
gtk_grid_attach(GTK_GRID(table), entry, 1, 0, 1, 1);
#else
gtk_table_attach(GTK_TABLE(table), entry, 1, 2, 0, 1,
GTK_EXPAND | GTK_FILL, (GtkAttachOptions) (0), 0, 0);
#endif
button = gtk_button_new_with_label("Change");
gtk_widget_show(button);
#if USE_GTK == 3
gtk_widget_set_hexpand(button, GTK_EXPAND | GTK_FILL);
gtk_grid_attach(GTK_GRID(table), button, 2, 0, 1, 1);
#else
gtk_table_attach(GTK_TABLE(table), button, 2, 3, 0, 1,
GTK_EXPAND | GTK_FILL, (GtkAttachOptions) (0), 0, 0);
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(e_cb_key_change), NULL);
m = gtk_menu_new();
gtk_widget_show(m);
mi = gtk_menu_item_new_with_label("NONE");
gtk_widget_show(mi);
gtk_signal_connect(GTK_OBJECT(mi), "activate",
GTK_SIGNAL_FUNC(e_cb_modifier), (gpointer) 0);
gtk_menu_append(GTK_MENU(m), mi);
{
gint i;
for (i = 1; i < 21; i++)
{
mi = gtk_menu_item_new_with_label(MOD_TEXT(i));
gtk_widget_show(mi);
gtk_signal_connect(GTK_OBJECT(mi), "activate",
GTK_SIGNAL_FUNC(e_cb_modifier),
(gpointer) (glong) i);
gtk_menu_append(GTK_MENU(m), mi);
}
}
#endif
g_signal_connect(G_OBJECT(button), "clicked",
G_CALLBACK(e_cb_key_change), NULL);
act_mod = om = gtk_option_menu_new();
gtk_widget_show(om);
gtk_option_menu_set_menu(GTK_OPTION_MENU(om), m);
gtk_option_menu_set_history(GTK_OPTION_MENU(om), 0);
act_mod = om = gtk_combo_box_text_new();
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(om), "None");
for (i = 1; i < 21; i++)
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(om), MOD_TEXT(i));
gtk_combo_box_set_active(GTK_COMBO_BOX(om), 0);
g_signal_connect(G_OBJECT(om), "changed", G_CALLBACK(e_cb_modifier), NULL);
#if USE_GTK == 3
gtk_widget_set_hexpand(om, GTK_EXPAND | GTK_FILL);
gtk_grid_attach(GTK_GRID(table), om, 1, 1, 2, 1);
#else
gtk_table_attach(GTK_TABLE(table), om, 1, 3, 1, 2,
GTK_EXPAND | GTK_FILL, (GtkAttachOptions) (0), 0, 0);
#endif
act_params = entry = gtk_entry_new_with_max_length(4096);
gtk_widget_show(entry);
act_params = entry = gtk_entry_new();
gtk_entry_set_max_length(GTK_ENTRY(entry), 4096);
gtk_widget_set_sensitive(entry, FALSE);
#if USE_GTK == 3
gtk_widget_set_hexpand(entry, GTK_EXPAND | GTK_FILL);
gtk_grid_attach(GTK_GRID(table), entry, 1, 2, 2, 1);
#else
gtk_table_attach(GTK_TABLE(table), entry, 1, 3, 2, 3,
GTK_EXPAND | GTK_FILL, (GtkAttachOptions) (0), 0, 0);
gtk_signal_connect(GTK_OBJECT(entry), "changed",