aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/events.c
diff options
context:
space:
mode:
authorGravatar Dieter Plaetinck <dieter@plaetinck.be>2010-01-02 11:50:21 +0100
committerGravatar Dieter Plaetinck <dieter@plaetinck.be>2010-01-02 11:50:21 +0100
commit7f8ef03cfd55c266de8b78bfa19e154e1e9047b6 (patch)
tree27f61780ca1d1f37d1d561d03e2ad1708f03ab40 /src/events.c
parentcf98a9a7f1713c81ba855f79de2a48aa1f994714 (diff)
move source files from project root into src directory. Makefile is a bit broken though
Diffstat (limited to 'src/events.c')
-rw-r--r--src/events.c206
1 files changed, 206 insertions, 0 deletions
diff --git a/src/events.c b/src/events.c
new file mode 100644
index 0000000..acb554c
--- /dev/null
+++ b/src/events.c
@@ -0,0 +1,206 @@
+/*
+ ** Uzbl event routines
+ ** (c) 2009 by Robert Manea
+*/
+
+#include "uzbl-core.h"
+#include "events.h"
+
+UzblCore uzbl;
+
+/* Event id to name mapping
+ * Event names must be in the same
+ * order as in 'enum event_type'
+ *
+ * TODO: Add more useful events
+*/
+const char *event_table[LAST_EVENT] = {
+ "LOAD_START" ,
+ "LOAD_COMMIT" ,
+ "LOAD_FINISH" ,
+ "LOAD_ERROR" ,
+ "KEY_PRESS" ,
+ "KEY_RELEASE" ,
+ "DOWNLOAD_REQUEST" ,
+ "COMMAND_EXECUTED" ,
+ "LINK_HOVER" ,
+ "TITLE_CHANGED" ,
+ "GEOMETRY_CHANGED" ,
+ "WEBINSPECTOR" ,
+ "NEW_WINDOW" ,
+ "SELECTION_CHANGED",
+ "VARIABLE_SET" ,
+ "FIFO_SET" ,
+ "SOCKET_SET" ,
+ "INSTANCE_START" ,
+ "INSTANCE_EXIT" ,
+ "LOAD_PROGRESS" ,
+ "LINK_UNHOVER" ,
+ "FORM_ACTIVE" ,
+ "ROOT_ACTIVE" ,
+ "FOCUS_LOST" ,
+ "FOCUS_GAINED" ,
+ "FILE_INCLUDED" ,
+ "PLUG_CREATED" ,
+ "COMMAND_ERROR" ,
+ "BUILTINS"
+};
+
+void
+event_buffer_timeout(guint sec) {
+ struct itimerval t;
+ memset(&t, 0, sizeof t);
+ t.it_value.tv_sec = sec;
+ t.it_value.tv_usec = 0;
+ setitimer(ITIMER_REAL, &t, NULL);
+}
+
+
+void
+send_event_socket(GString *msg) {
+ GError *error = NULL;
+ GString *tmp;
+ GIOChannel *gio = NULL;
+ GIOStatus ret;
+ gsize len;
+ guint i=0, j=0;
+
+ /* write to all --connect-socket sockets */
+ if(uzbl.comm.connect_chan) {
+ while(i < uzbl.comm.connect_chan->len) {
+ gio = g_ptr_array_index(uzbl.comm.connect_chan, i++);
+ j=0;
+
+ if(gio && gio->is_writeable) {
+ if(uzbl.state.event_buffer) {
+ event_buffer_timeout(0);
+
+ /* replay buffered events */
+ while(j < uzbl.state.event_buffer->len) {
+ tmp = g_ptr_array_index(uzbl.state.event_buffer, j++);
+ ret = g_io_channel_write_chars (gio,
+ tmp->str, tmp->len,
+ &len, &error);
+
+ if (ret == G_IO_STATUS_ERROR)
+ g_warning ("Error sending event to socket: %s", error->message);
+ else
+ g_io_channel_flush(gio, &error);
+ }
+ }
+
+ if(msg) {
+ ret = g_io_channel_write_chars (gio,
+ msg->str, msg->len,
+ &len, &error);
+
+ if (ret == G_IO_STATUS_ERROR)
+ g_warning ("Error sending event to socket: %s", error->message);
+ else
+ g_io_channel_flush(gio, &error);
+ }
+ }
+ }
+ if(uzbl.state.event_buffer) {
+ g_ptr_array_free(uzbl.state.event_buffer, TRUE);
+ uzbl.state.event_buffer = NULL;
+ }
+ }
+ /* buffer events until a socket is set and connected
+ * or a timeout is encountered
+ */
+ else {
+ if(!uzbl.state.event_buffer)
+ uzbl.state.event_buffer = g_ptr_array_new();
+ g_ptr_array_add(uzbl.state.event_buffer, (gpointer)g_string_new(msg->str));
+ }
+
+ /* write to all client sockets */
+ i=0;
+ if(msg && uzbl.comm.client_chan) {
+ while(i < uzbl.comm.client_chan->len) {
+ gio = g_ptr_array_index(uzbl.comm.client_chan, i++);
+
+ if(gio && gio->is_writeable && msg) {
+ ret = g_io_channel_write_chars (gio,
+ msg->str, msg->len,
+ &len, &error);
+
+ if (ret == G_IO_STATUS_ERROR)
+ g_warning ("Error sending event to socket: %s", error->message);
+ else
+ g_io_channel_flush(gio, &error);
+ }
+ }
+ }
+}
+
+void
+send_event_stdout(GString *msg) {
+ printf("%s", msg->str);
+ fflush(stdout);
+}
+
+/*
+ * build event string and send over the supported interfaces
+ * custom_event == NULL indicates an internal event
+*/
+void
+send_event(int type, const gchar *details, const gchar *custom_event) {
+ GString *event_message = g_string_new("");
+ gchar *buf, *p_val = NULL;
+
+ /* expand shell vars */
+ if(details) {
+ buf = g_strdup(details);
+ p_val = parseenv(buf ? g_strchug(buf) : " ");
+ g_free(buf);
+ }
+
+ /* check for custom events */
+ if(custom_event) {
+ g_string_printf(event_message, "EVENT [%s] %s %s\n",
+ uzbl.state.instance_name, custom_event, p_val);
+ }
+ /* check wether we support the internal event */
+ else if(type < LAST_EVENT) {
+ g_string_printf(event_message, "EVENT [%s] %s %s\n",
+ uzbl.state.instance_name, event_table[type], p_val);
+ }
+
+ if(event_message->str) {
+ if(uzbl.state.events_stdout)
+ send_event_stdout(event_message);
+ send_event_socket(event_message);
+
+ g_string_free(event_message, TRUE);
+ }
+ g_free(p_val);
+}
+
+/* Transform gdk key events to our own events */
+void
+key_to_event(guint keyval, gint mode) {
+ gchar ucs[7];
+ gint ulen;
+ guint32 ukval = gdk_keyval_to_unicode(keyval);
+
+ /* check for printable unicode char */
+ /* TODO: Pass the keyvals through a GtkIMContext so that
+ * we also get combining chars right
+ */
+ if(g_unichar_isgraph(ukval)) {
+ ulen = g_unichar_to_utf8(ukval, ucs);
+ ucs[ulen] = 0;
+
+ send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE,
+ ucs, NULL);
+ }
+ /* send keysym for non-printable chars */
+ else {
+ send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE,
+ gdk_keyval_name(keyval), NULL);
+ }
+
+}
+