summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEamon Walsh <ewalsh@tycho.nsa.gov>2009-07-29 17:34:39 -0400
committerEamon Walsh <ewalsh@tycho.nsa.gov>2009-07-29 17:34:39 -0400
commit1b2247c544a7d7ae5101ae26a786b89536e291bf (patch)
treee21e0bfe1dcb3af092431cf537369c05ea176e66 /src
parente7fa84d2281568d5d620dd6d1bde4f5044d14e50 (diff)
Initial input device monitor and interface tab.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am3
-rw-r--r--src/app.h1
-rw-r--r--src/inputmon.c493
-rw-r--r--src/main.c75
4 files changed, 216 insertions, 356 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index eca067a..c6bd887 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,7 +2,8 @@ pkgpythondir = $(pythondir)/xcb
bin_PROGRAMS = sedpymgr
-sedpymgr_SOURCES = main.c selmon.c selmgr.c propmon.c atom.c conn.c util.c
+sedpymgr_SOURCES = main.c selmon.c selmgr.c propmon.c inputmon.c \
+ atom.c conn.c util.c
sedpymgr_CFLAGS = $(SEDPYMGR_CFLAGS)
sedpymgr_LDADD = $(SEDPYMGR_LIBS)
diff --git a/src/app.h b/src/app.h
index 27a50f3..3eed720 100644
--- a/src/app.h
+++ b/src/app.h
@@ -9,6 +9,7 @@
#include <xcb/xselinux.h>
#include <X11/Xlib.h>
#include <X11/Xlib-xcb.h>
+#include <X11/extensions/XInput2.h>
#include <gtk/gtk.h>
enum {
diff --git a/src/inputmon.c b/src/inputmon.c
index d54add6..988d7c1 100644
--- a/src/inputmon.c
+++ b/src/inputmon.c
@@ -5,440 +5,227 @@
#include "app.h"
+Display *dpy;
static xcb_connection_t *conn;
static GtkTreeStore *store;
-xcb_window_t root;
+xcb_window_t window;
+
+static GHashTable *devices;
+
static void
setup_x(const gchar *display)
{
const xcb_setup_t *setup;
xcb_screen_iterator_t iter;
+ xcb_window_t root;
uint32_t mask, list;
+ XIEventMask all;
- conn = make_connection(display);
+ make_connection(display, &conn, &dpy);
setup = xcb_get_setup(conn);
iter = xcb_setup_roots_iterator(setup);
root = iter.data->root;
+ window = xcb_generate_id(conn);
+ xcb_create_window(conn, 0, window, root, 0, 0, 100, 100, 0,
+ XCB_WINDOW_CLASS_INPUT_ONLY, 0, 0, NULL);
+
atom_init(conn);
/* Select for root window events */
mask = XCB_CW_EVENT_MASK;
- list = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
+ list = XCB_EVENT_MASK_SUBSTRUCTURE_NOTIFY;
xcb_change_window_attributes(conn, root, mask, &list);
- xcb_flush(conn);
-}
-
-static char *
-get_prop_text(xcb_get_property_reply_t *reply)
-{
- size_t size;
- char *data;
-
- if (!atom_is_string_type(reply->type))
- return NULL;
-
- size = (reply->format >> 3) * xcb_get_property_value_length(reply);
-
- data = malloc(size + 1);
- if (!data)
- APP_ERR(NULL, "Out of memory");
-
- memcpy(data, xcb_get_property_value(reply), size);
- data[size] = '\0';
-
- return scrub_text(data);
-}
-
-static gboolean
-find_window(xcb_window_t window, GtkTreeIter *iter)
-{
- GtkTreeModel *tree = GTK_TREE_MODEL(store);
- xcb_window_t cur;
-
- if (gtk_tree_model_get_iter_first(tree, iter)) {
- do {
- gtk_tree_model_get(tree, iter, COL_WIN, &cur, -1);
- if (cur == window)
- return TRUE;
-
- } while (gtk_tree_model_iter_next(tree, iter));
- }
-
- return FALSE;
-}
-
-static void
-update_window_name(xcb_window_t window, const char *text)
-{
- GtkTreeIter iter;
- char buf[128];
-
- if (find_window(window, &iter)) {
- snprintf(buf, sizeof(buf), "%s (%08x)", text, window);
- gtk_tree_store_set(store, &iter, COL_NAME, buf, -1);
- }
-}
-
-static void
-add_item(GtkTreeIter *parent, GtkTreeIter *sibling,
- xcb_window_t window, xcb_atom_t atom,
- security_context_t octx, security_context_t dctx,
- xcb_atom_t type, const char *data)
-{
- GtkTreeIter iter;
- char *color;
-
- color = get_colors(octx, dctx);
+ /* Select for all device events */
+ mask = XI_HierarchyChangedMask;
+ all.deviceid = XIAllDevices;
+ all.mask_len = 1;
+ all.mask = (unsigned char *)&mask;
- gtk_tree_store_insert_before(store, &iter, parent, sibling);
- gtk_tree_store_set(store, &iter,
- COL_ICON, GTK_STOCK_FILE,
- COL_ATOM, atom,
- COL_WIN, window,
- COL_DATA, data,
- COL_NAME, atom_lookup(conn, atom),
- COL_TYPE, atom_lookup(conn, type),
- COL_OCTX, octx,
- COL_DCTX, dctx,
- COL_OFG, color,
- COL_OBG, color + 8,
- COL_DFG, color + 16,
- COL_DBG, color + 24,
- -1);
+ if (XISelectEvents(dpy, window, &all, 1) != Success)
+ APP_ERR(NULL, "An error was received during XISelectEvents.\n");
- free(color);
+ XFlush(dpy);
}
-static void
-remove_items(xcb_window_t window, xcb_atom_t atom)
-{
- GtkTreeModel *tree = GTK_TREE_MODEL(store);
- GtkTreeIter iter, child;
- xcb_atom_t iatom;
- int more;
-
- if (!find_window(window, &iter))
- return;
-
- if (gtk_tree_model_iter_children(tree, &child, &iter)) {
- do {
- gtk_tree_model_get(tree, &child, COL_ATOM, &iatom, -1);
- if (atom == iatom)
- more = gtk_tree_store_remove(store, &child);
- else
- more = gtk_tree_model_iter_next(tree, &child);
- } while (more);
+static char *
+get_use_text(int use)
+{
+ switch (use) {
+ case XIMasterPointer:
+ return "Master Pointer";
+ case XIMasterKeyboard:
+ return "Master Keyboard";
+ case XISlavePointer:
+ return "Slave Pointer";
+ case XISlaveKeyboard:
+ return "Slave Keyboard";
+ case XIFloatingSlave:
+ return "Floating Slave";
+ default:
+ return "Unknown";
}
}
-static int
-update_item_matches(GtkTreeIter *iter, xcb_atom_t atom, security_context_t ctx)
-{
- GtkTreeModel *tree = GTK_TREE_MODEL(store);
- xcb_atom_t iatom;
- security_context_t ictx;
- int result;
-
- gtk_tree_model_get(tree, iter, COL_ATOM, &iatom, COL_OCTX, &ictx, -1);
- result = (atom == iatom) && !strcmp(ctx, ictx);
- g_free(ictx);
- return result;
-}
-
static gboolean
-update_item_next(xcb_atom_t atom, GtkTreeIter *iter, GtkTreeIter **sibling)
-{
- GtkTreeModel *tree = GTK_TREE_MODEL(store);
- xcb_atom_t iatom;
- const char *name, *iname;
-
- gtk_tree_model_get(tree, iter, COL_ATOM, &iatom, -1);
- name = atom_lookup(conn, atom);
- iname = atom_lookup(conn, iatom);
-
- if (strcasecmp(name, iname) < 0) {
- *sibling = iter;
- return FALSE;
- }
-
- *sibling = NULL;
- return gtk_tree_model_iter_next(tree, iter);
-}
-
-static void
-update_item(xcb_window_t window, xcb_atom_t atom,
- security_context_t octx, security_context_t dctx,
- xcb_atom_t type, const char *data)
+find_device_helper(int id, GtkTreeIter *iter)
{
GtkTreeModel *tree = GTK_TREE_MODEL(store);
- GtkTreeIter iter, child, *sibling = NULL;
- char *color;
+ GtkTreeIter child;
+ int cur;
- if (!find_window(window, &iter))
- return;
+ gtk_tree_model_get(tree, iter, COL_ATOM, &cur, -1);
+ if (cur == id)
+ return TRUE;
- if (gtk_tree_model_iter_children(tree, &child, &iter)) {
+ if (gtk_tree_model_iter_children(tree, &child, iter)) {
do {
- if (update_item_matches(&child, atom, octx)) {
- color = get_colors(NULL, dctx);
- gtk_tree_store_set(store, &child,
- COL_DATA, data,
- COL_TYPE, atom_lookup(conn, type),
- COL_DCTX, dctx,
- COL_DFG, color + 16,
- COL_DBG, color + 24,
- -1);
- free(color);
- return;
+ if (find_device_helper(id, &child)) {
+ *iter = child;
+ return TRUE;
}
- } while (update_item_next(atom, &child, &sibling));
+ } while (gtk_tree_model_iter_next(tree, &child));
}
- add_item(&iter, sibling, window, atom, octx, dctx, type, data);
-}
+ while (gtk_tree_model_iter_next(tree, iter))
+ if (find_device_helper(id, iter))
+ return TRUE;
-static gboolean
-update_is_managed(xcb_atom_t atom, xcb_atom_t wildcard)
-{
- return (wildcard == XCB_NONE || wildcard == atom);
+ return FALSE;
}
-static void
-update(xcb_window_t window, xcb_atom_t atom)
+static gboolean
+find_device(int id, GtkTreeIter *iter)
{
- xcb_selinux_list_properties_cookie_t cookie;
- xcb_selinux_list_properties_reply_t *reply;
- xcb_get_property_cookie_t *cookies;
- xcb_get_property_reply_t *propinfo;
- xcb_generic_error_t *error;
- xcb_selinux_list_item_iterator_t iter;
- security_context_t octx, dctx;
- char *text;
- int i;
-
- /* remove existing items if updating */
- if (atom != XCB_NONE)
- remove_items(window, atom);
-
- /* list all property instances on the window */
- cookie = xcb_selinux_list_properties(conn, window);
- reply = xcb_selinux_list_properties_reply(conn, cookie, &error);
- if (error) {
- /* window might have gone away */
- if (error->error_code == XCB_WINDOW) {
- free(error);
- return;
- }
- APP_ERR(error, "An error was received during ListProperties.\n");
- }
-
- iter = xcb_selinux_list_properties_properties_iterator(reply);
- cookies = malloc(iter.rem * sizeof(*cookies));
- if (!cookies)
- APP_ERR(NULL, "Out of memory\n");
-
- /* get the property type and text content */
- i = 0;
- while (iter.rem) {
- if (update_is_managed(iter.data->name, atom)) {
- octx = xcb_selinux_list_item_object_context(iter.data);
- xcb_selinux_set_property_use_context(conn, strlen(octx) + 1, octx);
- cookies[i] = xcb_get_property(conn, FALSE, window, iter.data->name,
- XCB_GET_PROPERTY_TYPE_ANY, 0, 1024);
- }
- xcb_selinux_list_item_next(&iter);
- ++i;
- }
+ GtkTreeModel *tree = GTK_TREE_MODEL(store);
- /* process the replies */
- i = 0;
- iter = xcb_selinux_list_properties_properties_iterator(reply);
- while (iter.rem) {
- if (update_is_managed(iter.data->name, atom)) {
- octx = xcb_selinux_list_item_object_context(iter.data);
- dctx = xcb_selinux_list_item_data_context(iter.data);
- propinfo = xcb_get_property_reply(conn, cookies[i], &error);
- if (error)
- APP_ERR(error, "An error was received during GetProperty.\n");
-
- text = get_prop_text(propinfo);
- update_item(window, iter.data->name, octx, dctx, propinfo->type, text);
-
- /* special window updates */
- if (iter.data->name == wm_name)
- update_window_name(window, text);
-
- free(text);
- free(propinfo);
- }
- xcb_selinux_list_item_next(&iter);
- ++i;
- }
+ if (gtk_tree_model_get_iter_first(tree, iter))
+ return find_device_helper(id, iter);
- free(reply);
- free(cookies);
- xcb_flush(conn);
+ return FALSE;
}
static void
-add_window(xcb_window_t window)
+add_device(XIDeviceInfo *info)
{
- xcb_selinux_get_window_context_cookie_t cookie;
- xcb_selinux_get_window_context_reply_t *reply;
+ xcb_selinux_get_device_context_cookie_t cookie;
+ xcb_selinux_get_device_context_reply_t *reply;
xcb_generic_error_t *error;
security_context_t octx;
- uint32_t mask, list;
- GtkTreeIter iter;
- char *color, buf[24];
+ GtkTreeIter iter, parent;
+ char *color;
- /* Get window context */
- cookie = xcb_selinux_get_window_context(conn, window);
- reply = xcb_selinux_get_window_context_reply(conn, cookie, &error);
+ /* Get device context */
+ cookie = xcb_selinux_get_device_context(conn, info->deviceid);
+ reply = xcb_selinux_get_device_context_reply(conn, cookie, &error);
if (error)
- APP_ERR(error, "An error was received during GetWindowContext.\n");
+ APP_ERR(error, "An error was received during GetDeviceContext.\n");
- octx = xcb_selinux_get_window_context_context(reply);
+ octx = xcb_selinux_get_device_context_context(reply);
- /* Add window to list */
color = get_colors(octx, NULL);
- if (window == root)
- snprintf(buf, sizeof(buf), "root (%08x)", window);
- else
- snprintf(buf, sizeof(buf), "unnamed (%08x)", window);
- gtk_tree_store_append(store, &iter, NULL);
+ if (info->use == XIMasterPointer) {
+ /* Create toplevel row */
+ gtk_tree_store_append(store, &iter, NULL);
+ g_hash_table_insert(devices, octx, (gpointer)info->deviceid);
+ } else {
+ /* Create child row */
+ if (!find_device(info->attachment, &parent))
+ APP_ERR(NULL, "Device parent not found!\n");
+ gtk_tree_store_append(store, &iter, &parent);
+ }
+
+ /* Add device to list */
gtk_tree_store_set(store, &iter,
- COL_ICON, GTK_STOCK_DIRECTORY,
- COL_WIN, window,
- COL_NAME, buf,
+ COL_ICON, GTK_STOCK_FILE,
+ COL_NAME, info->name,
+ COL_ATOM, info->deviceid,
+ COL_WIN, info->attachment,
+ COL_TYPE, get_use_text(info->use),
COL_OCTX, octx,
COL_OFG, color,
COL_OBG, color + 8,
-1);
- /* Select for window events */
- if (window != root) {
- mask = XCB_CW_EVENT_MASK;
- list = XCB_EVENT_MASK_STRUCTURE_NOTIFY | XCB_EVENT_MASK_PROPERTY_CHANGE;
- xcb_change_window_attributes(conn, window, mask, &list);
- }
-
- update(window, XCB_NONE);
free(color);
- free(reply);
}
static void
-add_windows(void)
+update(void)
{
- xcb_query_tree_cookie_t cookie;
- xcb_query_tree_reply_t *reply;
- xcb_generic_error_t *error;
- xcb_window_t *children;
- int i;
-
- cookie = xcb_query_tree(conn, root);
- reply = xcb_query_tree_reply(conn, cookie, &error);
- if (error)
- APP_ERR(error, "An error was received during QueryTree.\n");
+ XIDeviceInfo *all;
+ int i, n;
- children = xcb_query_tree_children(reply);
+ gtk_tree_store_clear(store);
+ g_hash_table_remove_all(devices);
- add_window(root);
- for (i = 0; i < reply->children_len; i++)
- add_window(children[i]);
+ all = XIQueryDevice(dpy, XIAllDevices, &n);
- free(reply);
-}
+ for (i = 0; i < n; i++)
+ add_device(all + i);
-static void
-del_window_helper(xcb_window_t window, GtkTreeIter *iter)
-{
- GtkTreeModel *tree = GTK_TREE_MODEL(store);
- GtkTreeIter child;
- xcb_window_t cur;
- int more;
-
- do {
- gtk_tree_model_get(tree, iter, COL_WIN, &cur, -1);
- if (cur == window) {
- if (gtk_tree_model_iter_children(tree, &child, iter))
- del_window_helper(window, &child);
- more = gtk_tree_store_remove(store, iter);
- } else
- more = gtk_tree_model_iter_next(tree, iter);
- } while (more);
+ XIFreeDeviceInfo(all);
}
static void
-del_window(xcb_window_t window)
+handle_create(XCreateWindowEvent *event)
{
- GtkTreeModel *tree = GTK_TREE_MODEL(store);
- GtkTreeIter iter;
+ xcb_selinux_get_client_context_cookie_t cookie;
+ xcb_selinux_get_client_context_reply_t *reply;
+ xcb_generic_error_t *error;
+ security_context_t ctx;
+ int dev;
+ XIAnyHierarchyChangeInfo hci;
- if (gtk_tree_model_get_iter_first(tree, &iter))
- del_window_helper(window, &iter);
-}
+ /* Get client context */
+ cookie = xcb_selinux_get_client_context(conn, event->window);
+ reply = xcb_selinux_get_client_context_reply(conn, cookie, &error);
+ if (error) {
+ /* window might have gone away */
+ if (error->error_code == XCB_VALUE) {
+ free(error);
+ return;
+ }
+ APP_ERR(error, "An error was received during GetClientContext.\n");
+ }
-static void
-handle_property(xcb_property_notify_event_t *event)
-{
- update(event->window, event->atom);
-}
+ ctx = xcb_selinux_get_client_context_context(reply);
+ dev = (int)g_hash_table_lookup(devices, ctx);
-static void
-handle_create(xcb_create_notify_event_t *event)
-{
- add_window(event->window);
-}
+ /* Set device create context */
+ xcb_selinux_set_device_create_context(conn, strlen(ctx) + 1, ctx);
+ if (!dev) {
+ hci.add.type = XIAddMaster;
+ hci.add.name = "Protected";
+ hci.add.send_core = 0;
+ hci.add.enable = 1;
-static void
-handle_destroy(xcb_destroy_notify_event_t *event)
-{
- del_window(event->window);
+ /* Create master device pair for this context */
+ if (XIChangeHierarchy(dpy, &hci, 1) != Success)
+ APP_ERR(NULL, "An error was received during XIChangeHierarchy.\n");
+ }
}
static gboolean
handle_event(GIOChannel *source, GIOCondition condition, gpointer data)
{
- xcb_generic_event_t *event;
-
- while ((event = xcb_poll_for_event(conn))) {
- switch (event->response_type) {
- case XCB_PROPERTY_NOTIFY:
- handle_property((xcb_property_notify_event_t *)event);
- break;
-
- case XCB_CREATE_NOTIFY:
- handle_create((xcb_create_notify_event_t *)event);
- break;
-
- case XCB_DESTROY_NOTIFY:
- handle_destroy((xcb_destroy_notify_event_t *)event);
- break;
-
- case XCB_MAP_NOTIFY:
- case XCB_UNMAP_NOTIFY:
- case XCB_UNMAP_NOTIFY | 0x80:
- case XCB_CONFIGURE_NOTIFY:
- case XCB_CONFIGURE_NOTIFY | 0x80:
- case XCB_REPARENT_NOTIFY:
- case XCB_MAPPING_NOTIFY:
- case XCB_CLIENT_MESSAGE:
- case XCB_CLIENT_MESSAGE | 0x80:
- /* do nothing */
- break;
-
- default:
- fprintf(stderr, "Monitor: %d event\n", event->response_type);
- break;
- }
- free(event);
- xcb_flush(conn);
+ XEvent ev;
+ XGenericEventCookie *event = (XGenericEventCookie *)&ev;
+
+ while (XPending(dpy)) {
+ XNextEvent(dpy, &ev);
+
+ if (XGetEventData(dpy, event))
+ update();
+ else if (ev.type == CreateNotify)
+ handle_create((XCreateWindowEvent *)event);
+
+ XFreeEventData(dpy, event);
+ XFlush(dpy);
}
return TRUE;
@@ -452,6 +239,8 @@ input_monitor_init(struct thread_data *data)
store = GTK_TREE_STORE(data->store);
+ devices = g_hash_table_new(g_str_hash, g_str_equal);
+
setup_x(data->display);
fd = xcb_get_file_descriptor(conn);
@@ -459,7 +248,7 @@ input_monitor_init(struct thread_data *data)
g_io_channel_set_encoding(channel, NULL, NULL);
g_io_add_watch(channel, G_IO_IN|G_IO_ERR|G_IO_HUP, handle_event, NULL);
- add_windows();
+ update();
handle_event(channel, 0, NULL);
return 0;
diff --git a/src/main.c b/src/main.c
index 73bf1e2..e2e0b35 100644
--- a/src/main.c
+++ b/src/main.c
@@ -10,7 +10,7 @@
static GtkWidget *appwin;
static GtkWidget *expwin;
static GtkListStore *sel_store;
-static GtkTreeStore *prop_store;
+static GtkTreeStore *prop_store, *dev_store;
static unsigned timestamp;
static gboolean
@@ -156,6 +156,68 @@ create_sel_widget(void)
}
static GtkWidget *
+create_dev_widget(void)
+{
+ GtkTreeStore *store;
+ GtkTreeView *tree;
+ GtkTreeSelection *sel;
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ store = gtk_tree_store_new(N_COLS,
+ G_TYPE_STRING, /* SEL */
+ G_TYPE_LONG, /* ATOM */
+ G_TYPE_LONG, /* WIN */
+ G_TYPE_STRING, /* TYPE */
+ G_TYPE_STRING, /* DATA */
+ G_TYPE_STRING, /* OCTX */
+ G_TYPE_STRING, /* OFG */
+ G_TYPE_STRING, /* OBG */
+ G_TYPE_STRING, /* DCTX */
+ G_TYPE_STRING, /* DFG */
+ G_TYPE_STRING, /* DBG */
+ G_TYPE_STRING /* ICON */
+ );
+
+ tree = GTK_TREE_VIEW(gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)));
+ sel = gtk_tree_view_get_selection(tree);
+ gtk_tree_selection_set_mode(sel, GTK_SELECTION_SINGLE);
+
+ renderer = gtk_cell_renderer_pixbuf_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ "", renderer,
+ "stock-id", COL_ICON,
+ NULL);
+ gtk_tree_view_append_column(tree, column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ "Name", renderer,
+ "text", COL_NAME,
+ NULL);
+ gtk_tree_view_append_column(tree, column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ "Type", renderer,
+ "text", COL_TYPE,
+ NULL);
+ gtk_tree_view_append_column(tree, column);
+
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(
+ "Level", renderer,
+ "text", COL_OCTX,
+ "foreground", COL_OFG,
+ "background", COL_OBG,
+ NULL);
+ gtk_tree_view_append_column(tree, column);
+
+ dev_store = store;
+ return GTK_WIDGET(tree);
+}
+
+static GtkWidget *
create_prop_widget(void)
{
GtkTreeStore *store;
@@ -304,6 +366,7 @@ create_gui(void)
{
GtkWidget *selw = create_sel_widget();
GtkWidget *propw = create_prop_widget();
+ GtkWidget *devw = create_dev_widget();
GtkWidget *menubar = create_menu();
GtkWidget *scroll, *box, *tabs;
@@ -324,6 +387,10 @@ create_gui(void)
gtk_container_add(GTK_CONTAINER(scroll), propw);
gtk_notebook_append_page(GTK_NOTEBOOK(tabs), scroll, gtk_label_new("Properties"));
+ scroll = gtk_scrolled_window_new(NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(scroll), devw);
+ gtk_notebook_append_page(GTK_NOTEBOOK(tabs), scroll, gtk_label_new("Devices"));
+
box = gtk_vbox_new(FALSE, 0);
gtk_box_pack_start(GTK_BOX(box), menubar, FALSE, TRUE, 0);
gtk_box_pack_start(GTK_BOX(box), tabs, TRUE, TRUE, 0);
@@ -342,17 +409,19 @@ main(int argc, char **argv)
create_gui();
data.display = gdk_display_get_name(gdk_display_get_default());
- data.store = GTK_TREE_MODEL(sel_store);
data.appwin = appwin;
data.expwin = expwin;
+ data.store = GTK_TREE_MODEL(sel_store);
sel_manager_init(&data);
sel_monitor_init(&data);
data.store = GTK_TREE_MODEL(prop_store);
-
prop_monitor_init(&data);
+ data.store = GTK_TREE_MODEL(dev_store);
+ input_monitor_init(&data);
+
gtk_widget_show_all(appwin);
gtk_main();