You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1256 lines
35 KiB
1256 lines
35 KiB
#include "config.h" |
|
|
|
#include <gtk/gtk.h> |
|
#include <ctype.h> |
|
#include <locale.h> |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <string.h> |
|
#include <sys/stat.h> |
|
#include <X11/Xlib.h> |
|
#include <X11/XKBlib.h> |
|
#include <gdk/gdkx.h> |
|
#include <unistd.h> |
|
|
|
#include "e16keyedit.h" |
|
|
|
#if USE_GTK == 3 |
|
#define USE_GTK_TREEVIEW 1 |
|
#else |
|
#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)) |
|
|
|
GtkAccelGroup *accel_group; |
|
|
|
static GtkWidget *clist; |
|
static GtkWidget *act_key; |
|
static GtkWidget *act_params; |
|
static GtkWidget *act_mod; |
|
static GtkWidget *act_clist; |
|
|
|
static gchar *e_ipc_msg = NULL; |
|
static char dont_update = 0; |
|
static int last_row = 0; |
|
static int real_rows = 0; |
|
|
|
typedef struct |
|
{ |
|
const char *name_short; |
|
const char *name_long; |
|
} Modifier; |
|
|
|
typedef struct |
|
{ |
|
const char *text; |
|
gchar param_tpe; |
|
const char *params; |
|
const char *command; |
|
} ActionOpt; |
|
|
|
/* *INDENT-OFF* */ |
|
static const Modifier modifiers[] = { |
|
{"-", ""}, |
|
{"C", "CTRL"}, |
|
{"S", "SHIFT"}, |
|
{"A", "ALT"}, |
|
{"CS", "CTRL+SHIFT"}, |
|
{"CA", "CTRL+ALT"}, |
|
{"SA", "ALT+SHIFT"}, |
|
{"CSA", "CTRL+ALT+SHIFT"}, |
|
{"2", "MOD2"}, |
|
{"3", "MOD3"}, |
|
{"4", "MOD4"}, |
|
{"5", "MOD5"}, |
|
{"C2", "MOD2+CTRL"}, |
|
{"S2", "MOD2+SHIFT"}, |
|
{"A2", "MOD2+ALT"}, |
|
{"C4", "MOD4+CTRL"}, |
|
{"S4", "MOD4+SHIFT"}, |
|
{"A4", "MOD4+ALT"}, |
|
{"CS4", "MOD4+CTRL+SHIFT"}, |
|
{"C5", "MOD5+CTRL"}, |
|
{"S5", "MOD5+SHIFT"}, |
|
{"A5", "MOD5+ALT"}, |
|
{"CS5", "MOD5+CTRL+SHIFT"}, |
|
}; |
|
#define N_MODIFIERS (sizeof(modifiers)/sizeof(Modifier)) |
|
#define MOD_TEXT(mod) modifiers[mod].name_long |
|
|
|
static const ActionOpt actions_default[] = { |
|
{"Run command", 1, NULL, "exec "}, |
|
|
|
{"Restart Enlightenment", 0, "restart", "restart"}, |
|
{"Exit Enlightenment", 0, NULL, "exit"}, |
|
|
|
{"Goto Next Desktop", 0, NULL, "desk next"}, |
|
{"Goto Previous Deskop", 0, NULL, "desk prev"}, |
|
{"Goto Desktop", 2, NULL, "desk goto "}, |
|
{"Raise Desktop", 0, NULL, "desk raise"}, |
|
{"Lower Desktop", 0, NULL, "desk lower"}, |
|
{"Reset Desktop In Place", 0, NULL, "desk this"}, |
|
|
|
{"Cleanup Windows", 0, NULL, "misc arrange size"}, |
|
|
|
{"Move mouse pointer to next screen", 0, NULL, "warp screen"}, |
|
|
|
{"Move mouse pointer to left", 0, "-1 0", "warp rel -1 0"}, |
|
{"Move mouse pointer to right", 0, "1 0", "warp rel 1 0"}, |
|
{"Move mouse pointer up", 0, "0 -1", "warp rel 0 -1"}, |
|
{"Move mouse pointer down", 0, "0 1", "warp rel 0 1"}, |
|
{"Move mouse pointer by [X Y]", 3, NULL, "warp rel "}, |
|
|
|
{"Goto Desktop area [X Y]", 3, NULL, "area goto"}, |
|
{"Move to Desktop area on the left", 0, "-1 0", "area move -1 0"}, |
|
{"Move to Desktop area on the right", 0, "1 0", "area move 1 0"}, |
|
{"Move to Desktop area above", 0, "0 -1", "area move 0 -1"}, |
|
{"Move to Desktop area below", 0, "0 1", "area move 0 1"}, |
|
|
|
{"Raise Window", 0, NULL, "wop * raise"}, |
|
{"Lower Window", 0, NULL, "wop * lower"}, |
|
{"Close Window", 0, NULL, "wop * close"}, |
|
{"Annihilate Window", 0, NULL, "wop * kill"}, |
|
{"Stick / Unstick Window", 0, NULL, "wop * stick"}, |
|
{"Iconify Window", 0, NULL, "wop * iconify"}, |
|
{"Shade / Unshade Window", 0, NULL, "wop * shade"}, |
|
{"Maximise Height of Window", 0, "conservative", "wop * th conservative"}, |
|
{"Maximise Height of Window to available space", 0, "available", "wop * th available"}, |
|
{"Maximise Height of Window to whole screen", 0, NULL, "wop * th"}, |
|
{"Maximise Width of Window", 0, "conservative", "wop * tw conservative"}, |
|
{"Maximise Width of Window to available space", 0, "available", "wop * tw available"}, |
|
{"Maximise Width of Window to whole screen", 0, NULL, "wop * tw"}, |
|
{"Maximise Size of Window", 0, "conservative", "wop * ts conservative"}, |
|
{"Maximise Size of Window to available space", 0, "available", "wop * ts available"}, |
|
{"Maximise Size of Window to whole screen", 0, NULL, "wop * ts"}, |
|
{"Toggle Window fullscreen state", 0, NULL, "wop * fullscreen"}, |
|
{"Toggle Window zoom state", 0, NULL, "wop * zoom"}, |
|
{"Send window to next desktop", 0, NULL, "wop * desk next"}, |
|
{"Send window to previous desktop", 0, NULL, "wop * desk prev"}, |
|
{"Switch focus to next window", 0, NULL, "focus next"}, |
|
{"Switch focus to previous window", 0, NULL, "focus prev"}, |
|
{"Glue / Unglue Window to Desktop screen", 0, NULL, "wop * no_user_move"}, |
|
{"Set Window layer to On Top", 0, "20", "wop * layer 20"}, |
|
{"Set Window layer to Above", 0, "6", "wop * layer 6"}, |
|
{"Set Window layer to Normal", 0, "4", "wop * layer 4"}, |
|
{"Set Window layer to Below", 0, "2", "wop * layer 2"}, |
|
{"Set Window layer", 2, NULL, "wop * layer "}, |
|
{"Move Window to area on left", 0, "-1 0", "wop * area move -1 0"}, |
|
{"Move Window to area on right", 0, "1 0", "wop * area move 1 0"}, |
|
{"Move Window to area above", 0, "0 -1", "wop * area move 0 -1"}, |
|
{"Move Window to area below", 0, "0 1", "wop * area move 0 1"}, |
|
{"Move Window by area [X Y]", 3, NULL, "wop * area "}, |
|
|
|
{"Set Window border style to the Default", 0, "DEFAULT", "wop * border DEFAULT"}, |
|
{"Set Window border style to the Borderless", 0, "BORDERLESS", "wop * border BORDERLESS"}, |
|
|
|
{"Forget everything about Window", 0, "none", "wop * snap none"}, |
|
{"Remember all Window settings", 0, NULL, "wop * snap all"}, |
|
{"Remember Window Border", 0, "border", "wop * snap border"}, |
|
{"Remember Window Desktop", 0, "desktop", "wop * snap desktop"}, |
|
{"Remember Window Desktop Area", 0, "area", "wop * snap area"}, |
|
{"Remember Window Size", 0, "size", "wop * snap size"}, |
|
{"Remember Window Location", 0, "location", "wop * snap location"}, |
|
{"Remember Window Layer", 0, "layer", "wop * snap layer"}, |
|
{"Remember Window Stickyness", 0, "sticky", "wop * snap sticky"}, |
|
{"Remember Window Shadedness", 0, "shade", "wop * snap shade"}, |
|
|
|
{"Show Root Menu", 0, "ROOT_2", "menus show ROOT_2"}, |
|
{"Show Winops Menu", 0, "WINOPS_MENU", "menus show WINOPS_MENU"}, |
|
{"Show Named Menu", 1, NULL, "menus show "}, |
|
|
|
{NULL, 0, NULL, NULL} |
|
}; |
|
/* *INDENT-ON* */ |
|
|
|
static const ActionOpt *actions = NULL; |
|
static unsigned int action_count = sizeof(actions_default) / sizeof(ActionOpt); |
|
static unsigned int *action_index_to_row = NULL; |
|
static unsigned int *action_row_to_index = NULL; |
|
|
|
static int |
|
match_action_by_binding(const char *params) |
|
{ |
|
int k, len; |
|
|
|
for (k = 0; actions[k].text; k++) |
|
{ |
|
len = strlen(actions[k].command); |
|
if (strncmp(actions[k].command, params, len)) |
|
continue; |
|
|
|
return k; |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
static int |
|
match_action_by_selection(const char *text) |
|
{ |
|
int k; |
|
|
|
for (k = 0; actions[k].text; k++) |
|
{ |
|
if (strcmp(text, actions[k].text)) |
|
continue; |
|
|
|
return k; |
|
} |
|
|
|
return -1; |
|
} |
|
|
|
static unsigned |
|
mod_short_to_index(const char *name_short) |
|
{ |
|
unsigned int k; |
|
|
|
for (k = 0; k < N_MODIFIERS; k++) |
|
{ |
|
if (!strcmp(name_short, modifiers[k].name_short)) |
|
return k; |
|
} |
|
|
|
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_position(GTK_WINDOW(win), GTK_WIN_POS_MOUSE); |
|
frame = gtk_frame_new(NULL); |
|
gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT); |
|
align = gtk_alignment_new(0.0, 0.0, 0.0, 0.0); |
|
gtk_container_set_border_width(GTK_CONTAINER(align), 32); |
|
label = gtk_label_new("Please press the key on the keyboard\n" |
|
"you wish to modify this keyboard-shortcut\n" |
|
"to use from now on."); |
|
gtk_container_add(GTK_CONTAINER(win), frame); |
|
gtk_container_add(GTK_CONTAINER(frame), align); |
|
gtk_container_add(GTK_CONTAINER(align), label); |
|
gtk_widget_show_all(win); |
|
while (gtk_events_pending()) |
|
gtk_main_iteration(); |
|
gdk_flush(); |
|
while (gtk_events_pending()) |
|
gtk_main_iteration(); |
|
|
|
{ |
|
char *key; |
|
XEvent ev; |
|
|
|
#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); |
|
XWindowEvent(gdk_x11_get_default_xdisplay(), WIDGET_XID(win), |
|
KeyPressMask, &ev); |
|
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); |
|
clist_row_current_set_value(clist, 1, key); |
|
} |
|
|
|
gtk_widget_destroy(win); |
|
} |
|
|
|
static void |
|
e_cb_modifier(GtkWidget * widget, gpointer data __UNUSED__) |
|
{ |
|
int i; |
|
|
|
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) |
|
{ |
|
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_editable_set_editable(GTK_EDITABLE(act_params), TRUE); |
|
gtk_widget_set_sensitive(act_params, TRUE); |
|
} |
|
else |
|
{ |
|
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 *"); |
|
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 * |
|
dupcat(char *dst, const char *src) |
|
{ |
|
char *s; |
|
int len1, len2; |
|
|
|
if (!dst) |
|
return strdup(src); |
|
|
|
len1 = strlen(dst); |
|
len2 = strlen(src); |
|
|
|
s = realloc(dst, len1 + len2 + 1); |
|
strcpy(s + len1, src); |
|
|
|
return s; |
|
} |
|
|
|
static void |
|
on_save_data(void) |
|
{ |
|
char *buf = NULL; |
|
|
|
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 *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)) |
|
{ |
|
modifier = j; |
|
} |
|
} |
|
snprintf(tmp, sizeof(tmp), "%s %s %s %s\n", "KeyDown", |
|
modifiers[modifier].name_short, key, prm); |
|
buf = dupcat(buf, tmp); |
|
} |
|
|
|
#if DEBUG > 0 |
|
printf("%s", buf); |
|
#endif |
|
CommsSend(buf); |
|
#if 0 |
|
CommsSend("save_config"); |
|
#endif |
|
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 *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; |
|
|
|
#if USE_GTK_TREEVIEW |
|
GtkTreeIter iter; |
|
GtkTreeModel *model; |
|
|
|
if (gtk_tree_selection_get_selected(sel, &model, &iter)) |
|
{ |
|
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 |
|
|
|
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(act); |
|
if (i < 0 || actions[i].param_tpe == 0) |
|
{ |
|
gtk_editable_set_editable(GTK_EDITABLE(act_params), FALSE); |
|
gtk_widget_set_sensitive(act_params, FALSE); |
|
} |
|
else |
|
{ |
|
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]; |
|
clist_row_moveto(act_clist, i); |
|
} |
|
|
|
/* printf("%s\n%s\n%s\n%s\n",mod,key,act,prm); */ |
|
|
|
last_row = row; |
|
|
|
dont_update = 0; |
|
} |
|
|
|
static gchar *get_line(gchar * str, int num); |
|
|
|
static gchar * |
|
get_line(gchar * str, int num) |
|
{ |
|
gchar *s1, *s2, *s; |
|
gint i, count, l; |
|
|
|
i = 0; |
|
count = 0; |
|
s1 = str; |
|
if (*str == '\n') |
|
i = 1; |
|
s2 = NULL; |
|
for (i = 0;; i++) |
|
{ |
|
if ((str[i] == '\n') || (str[i] == 0)) |
|
{ |
|
s2 = &(str[i]); |
|
if ((count == num) && (s2 > s1)) |
|
{ |
|
l = s2 - s1; |
|
s = g_malloc(l + 1); |
|
strncpy(s, s1, l); |
|
s[l] = 0; |
|
return s; |
|
} |
|
count++; |
|
if (str[i] == 0) |
|
return NULL; |
|
s1 = s2 + 1; |
|
} |
|
} |
|
} |
|
|
|
#if ENABLE_SORTING |
|
static void |
|
on_resort_columns(GtkWidget * widget __UNUSED__, gint column, |
|
gpointer data __UNUSED__) |
|
{ |
|
static int order = 0; |
|
static int last_col = 0; |
|
|
|
gtk_clist_set_sort_column(GTK_CLIST(clist), column); |
|
if (last_col == column) |
|
{ |
|
if (order) |
|
{ |
|
order = 0; |
|
gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_DESCENDING); |
|
} |
|
else |
|
{ |
|
order = 1; |
|
gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING); |
|
} |
|
} |
|
else |
|
{ |
|
order = 1; |
|
gtk_clist_set_sort_type(GTK_CLIST(clist), GTK_SORT_ASCENDING); |
|
last_col = 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--; |
|
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] = ""; |
|
stuff[1] = ""; |
|
stuff[2] = ""; |
|
stuff[3] = ""; |
|
gtk_clist_select_row(GTK_CLIST(clist), |
|
gtk_clist_append(GTK_CLIST(clist), stuff), 0); |
|
#endif |
|
|
|
last_row = real_rows++; |
|
clist_row_moveto(clist, last_row); |
|
} |
|
|
|
static void |
|
on_change_params(GtkWidget * widget, gpointer data __UNUSED__) |
|
{ |
|
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(void) |
|
{ |
|
exit(0); |
|
} |
|
|
|
static void |
|
on_save_and_exit_application(void) |
|
{ |
|
on_save_data(); |
|
on_exit_application(); |
|
} |
|
|
|
static GtkWidget * |
|
create_list_window(void) |
|
{ |
|
GtkWidget *list_window; |
|
GtkWidget *bigvbox; |
|
GtkWidget *menubar; |
|
GtkWidget *panes; |
|
GtkWidget *scrollybit; |
|
GtkWidget *vbox; |
|
GtkWidget *frames; |
|
GtkWidget *alignment; |
|
GtkWidget *frame_vbox; |
|
GtkWidget *table; |
|
GtkWidget *label; |
|
GtkWidget *entry; |
|
GtkWidget *button; |
|
GtkWidget *hbox; |
|
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); |
|
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_container_add(GTK_CONTAINER(list_window), bigvbox); |
|
|
|
menubar = gtk_menu_bar_new(); |
|
gtk_box_pack_start(GTK_BOX(bigvbox), menubar, FALSE, FALSE, 0); |
|
|
|
menu = CreateBarSubMenu(menubar, "File"); |
|
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(); |
|
#endif |
|
gtk_box_pack_start(GTK_BOX(bigvbox), panes, TRUE, TRUE, 0); |
|
|
|
scrollybit = gtk_scrolled_window_new(NULL, NULL); |
|
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_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)); |
|
#endif |
|
gtk_container_add(GTK_CONTAINER(scrollybit), clist); |
|
|
|
{ |
|
char *msg, *buf; |
|
int j, k, modifier; |
|
char event[128], mod[128], key[128], *params; |
|
const char *stuff[4]; |
|
int len; |
|
|
|
CommsSend("ac kb"); |
|
msg = wait_for_ipc_msg(); |
|
i = 0; |
|
while ((buf = get_line(msg, i++))) |
|
{ |
|
if (strlen(buf) < 1) |
|
break; |
|
|
|
j = sscanf(buf, "%127s %127s %127s %n", event, mod, key, &len); |
|
#if DEBUG > 0 |
|
printf("buf(%d): %s\n", j, buf); |
|
#endif |
|
if (j < 3) |
|
goto next; |
|
if (strcmp(event, "KeyDown")) |
|
goto next; |
|
|
|
params = buf + len; |
|
#if DEBUG > 0 |
|
printf("event: %s, mod: %s, key: %s, params: %s\n", |
|
event, mod, key, params); |
|
#endif |
|
|
|
modifier = mod_short_to_index(mod); |
|
|
|
k = match_action_by_binding(params); |
|
|
|
#if DEBUG > 1 |
|
printf("key: %s, mod: %s, act=%d, params: %s\n", key, |
|
MOD_TEXT(modifier), k, params); |
|
#endif |
|
|
|
stuff[0] = MOD_TEXT(modifier); |
|
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: |
|
g_free(buf); |
|
} |
|
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); |
|
frames = gtk_frame_new("Edit Keybinding Properties"); |
|
gtk_container_set_border_width(GTK_CONTAINER(frames), 2); |
|
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_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_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_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT); |
|
#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_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT); |
|
#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_label_set_justify(GTK_LABEL(label), GTK_JUSTIFY_RIGHT); |
|
#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(); |
|
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"); |
|
#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); |
|
#endif |
|
g_signal_connect(G_OBJECT(button), "clicked", |
|
G_CALLBACK(e_cb_key_change), NULL); |
|
|
|
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(); |
|
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); |
|
#endif |
|
g_signal_connect(G_OBJECT(entry), "changed", |
|
G_CALLBACK(on_change_params), NULL); |
|
|
|
scrollybit = gtk_scrolled_window_new(NULL, NULL); |
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollybit), |
|
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); |
|
|
|
#if USE_GTK_TREEVIEW |
|
act_clist = gtk_tree_view_new(); |
|
|
|
renderer = gtk_cell_renderer_text_new(); |
|
gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(act_clist), |
|
-1, "Action Used:", renderer, |
|
"text", 0, NULL); |
|
|
|
store = gtk_list_store_new(1, G_TYPE_STRING); |
|
#else |
|
act_clist = gtk_clist_new(1); |
|
gtk_clist_set_column_title(GTK_CLIST(act_clist), 0, "Action Used:"); |
|
gtk_clist_column_titles_show(GTK_CLIST(act_clist)); |
|
#endif |
|
gtk_box_pack_start(GTK_BOX(frame_vbox), scrollybit, TRUE, TRUE, 0); |
|
gtk_container_add(GTK_CONTAINER(scrollybit), act_clist); |
|
|
|
{ |
|
const char *stuff[1]; |
|
int k, row; |
|
|
|
action_index_to_row = calloc(action_count, sizeof(int)); |
|
action_row_to_index = calloc(action_count, sizeof(int)); |
|
|
|
for (k = row = 0; (actions[k].text); k++) |
|
{ |
|
stuff[0] = actions[k].text; |
|
#if USE_GTK_TREEVIEW |
|
gtk_list_store_append(store, &iter); |
|
gtk_list_store_set(store, &iter, 0, stuff[0], -1); |
|
#else |
|
gtk_clist_append(GTK_CLIST(act_clist), (char **)stuff); |
|
#endif |
|
action_index_to_row[k] = row; |
|
action_row_to_index[row++] = k; |
|
} |
|
} |
|
#if USE_GTK_TREEVIEW |
|
gtk_tree_view_set_model(GTK_TREE_VIEW(act_clist), GTK_TREE_MODEL(store)); |
|
g_object_unref(store); |
|
sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(act_clist)); |
|
gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE); |
|
g_signal_connect(G_OBJECT(sel), "changed", G_CALLBACK(change_action), NULL); |
|
#else |
|
g_signal_connect(G_OBJECT(act_clist), "select_row", |
|
G_CALLBACK(change_action), NULL); |
|
#endif |
|
|
|
hbox = gtk_hbox_new(FALSE, 0); |
|
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); |
|
|
|
button = gtk_button_new_with_label(" New Keybinding "); |
|
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 5); |
|
g_signal_connect(G_OBJECT(button), "clicked", |
|
G_CALLBACK(on_create_row), NULL); |
|
|
|
button = gtk_button_new_with_label(" Delete Current Row "); |
|
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 5); |
|
g_signal_connect(G_OBJECT(button), "clicked", |
|
G_CALLBACK(on_delete_row), NULL); |
|
|
|
button = gtk_button_new_with_label(" Save "); |
|
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 5); |
|
g_signal_connect(G_OBJECT(button), "clicked", |
|
G_CALLBACK(on_save_data), NULL); |
|
|
|
button = gtk_button_new_with_label(" Quit "); |
|
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 5); |
|
g_signal_connect(G_OBJECT(button), "clicked", |
|
G_CALLBACK(on_exit_application), NULL); |
|
|
|
clist_row_moveto(clist, 0); |
|
|
|
return list_window; |
|
} |
|
|
|
static void |
|
receive_ipc_msg(gchar * msg) |
|
{ |
|
e_ipc_msg = g_strdup(msg); |
|
} |
|
|
|
static void |
|
check_e16_version(void) |
|
{ |
|
char *msg; |
|
const char *s; |
|
int ver, major, minor, micro; |
|
|
|
ver = major = minor = micro = 0; |
|
|
|
CommsSend("ver"); |
|
msg = wait_for_ipc_msg(); |
|
if (!msg) |
|
goto do_check; |
|
|
|
s = msg; |
|
while (*s && *s != '.') |
|
s++; |
|
s--; |
|
sscanf(s, "%d.%d.%d", &major, &minor, µ); |
|
ver = VER(major, minor, micro); |
|
|
|
free(msg); |
|
|
|
do_check: |
|
if (ver < VER(1, 0, 1)) |
|
{ |
|
printf("Sorry, e16 version >= 1.0.1 is required.\n"); |
|
exit(1); |
|
} |
|
} |
|
|
|
static void |
|
load_actions(void) |
|
{ |
|
char kbdb[1024], buf[1024], text[1024], command[1024]; |
|
char *s; |
|
FILE *f; |
|
int n, opt; |
|
unsigned int nao; |
|
ActionOpt *pao; |
|
|
|
actions = actions_default; |
|
|
|
/* FIXME - Should be fetched via IPC. */ |
|
|
|
s = getenv("EROOT"); |
|
if (!s) |
|
s = DATADIR "/e16"; /* Default location */ |
|
|
|
snprintf(kbdb, sizeof(kbdb), "%s/config/e16keyedit.db", s); |
|
|
|
f = fopen(kbdb, "r"); |
|
if (!f) |
|
return; |
|
|
|
nao = 0; |
|
pao = NULL; |
|
for (;;) |
|
{ |
|
s = fgets(buf, sizeof(buf), f); |
|
if (!s) |
|
break; |
|
while (isspace(*s)) |
|
s++; |
|
if (*s == '\0' || *s == '#') |
|
continue; |
|
n = strlen(s); |
|
while (n > 0 && (s[n - 1] == '\n' || s[n - 1] == '\r')) |
|
n--; |
|
if (n <= 0) |
|
continue; |
|
s[n] = '\0'; |
|
|
|
#if DEBUG > 0 |
|
printf("Got: %s\n", s); |
|
#endif |
|
text[0] = command[0] = '\0'; |
|
opt = -1; |
|
n = sscanf(s, "\"%1023[^\"]\", %d, \"%1023[^\"]\"", text, &opt, |
|
command); |
|
if (n < 2) |
|
{ |
|
printf("*** ERROR: %s\n", buf); |
|
printf |
|
("*** ERROR: Keybindings database (%s) corrupt, using defaults.\n", |
|
kbdb); |
|
if (pao) |
|
free(pao); |
|
fclose(f); |
|
return; |
|
} |
|
if (!command[0]) |
|
continue; |
|
#if DEBUG > 0 |
|
printf("n=%d t=%s o=%d c=%s\n", n, text, opt, command); |
|
#endif |
|
|
|
pao = realloc(pao, (nao + 1) * sizeof(ActionOpt)); |
|
memset(pao + nao, 0, sizeof(ActionOpt)); |
|
pao[nao].text = strdup(text); |
|
pao[nao].param_tpe = opt; |
|
pao[nao].command = strdup(command); |
|
nao++; |
|
} |
|
fclose(f); |
|
|
|
if (nao == 0) |
|
return; /* No entries ??? */ |
|
|
|
/* Add terminator record */ |
|
pao = realloc(pao, (nao + 1) * sizeof(ActionOpt)); |
|
memset(pao + nao, 0, sizeof(ActionOpt)); |
|
|
|
actions = pao; |
|
action_count = nao; |
|
} |
|
|
|
int |
|
main(int argc, char *argv[]) |
|
{ |
|
GtkWidget *lister; |
|
|
|
setlocale(LC_ALL, ""); |
|
|
|
gtk_init(&argc, &argv); |
|
|
|
accel_group = gtk_accel_group_new(); |
|
|
|
if (CommsInit(receive_ipc_msg)) |
|
{ |
|
GtkWidget *win, *label, *align, *frame, *button, *vbox; |
|
|
|
win = gtk_window_new(GTK_WINDOW_POPUP); |
|
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); |
|
align = gtk_alignment_new(0.0, 0.0, 0.0, 0.0); |
|
gtk_container_set_border_width(GTK_CONTAINER(align), 32); |
|
vbox = gtk_vbox_new(FALSE, 5); |
|
button = gtk_button_new_with_label("Quit"); |
|
g_signal_connect(G_OBJECT(button), "clicked", |
|
G_CALLBACK(on_exit_application), NULL); |
|
label = gtk_label_new("You are not running Enlightenment\n" |
|
"\n" |
|
"This window manager has to be running in order\n" |
|
"to configure it.\n" "\n"); |
|
gtk_container_add(GTK_CONTAINER(win), frame); |
|
gtk_container_add(GTK_CONTAINER(frame), align); |
|
gtk_container_add(GTK_CONTAINER(align), vbox); |
|
gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); |
|
gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); |
|
gtk_widget_show_all(win); |
|
gtk_main(); |
|
exit(1); |
|
} |
|
|
|
CommsSend("set clientname Enlightenment Keybinding Configuration Utility"); |
|
CommsSend("set version " VERSION); |
|
#if 0 |
|
CommsSend("set author Mandrake (Geoff Harrison)"); |
|
CommsSend("set email mandrake@mandrake.net"); |
|
CommsSend("set web http://mandrake.net/"); |
|
CommsSend("set address C/O VA Linux Systems, USA"); |
|
CommsSend("set info " |
|
"This is the Enlightenemnt KeyBindings Configuration Utility\n" |
|
"that uses Enlightenment's IPC mechanism to configure\n" |
|
"it remotely."); |
|
#endif |
|
|
|
check_e16_version(); |
|
|
|
load_actions(); |
|
|
|
lister = create_list_window(); |
|
|
|
g_signal_connect(G_OBJECT(lister), "destroy", |
|
G_CALLBACK(on_exit_application), NULL); |
|
g_signal_connect(G_OBJECT(lister), "delete_event", |
|
G_CALLBACK(on_exit_application), NULL); |
|
|
|
gtk_widget_show_all(lister); |
|
gtk_main(); |
|
|
|
return 0; |
|
}
|
|
|