Introduction
Introduction Statistics Contact Development Disclaimer Help
tsupporting multiple windows per instance - surf - customized build of surf, th…
git clone git://src.adamsgaard.dk/surf
Log
Files
Refs
README
LICENSE
---
commit ad005db13f571dabb72fce448eb0d93f79acf97d
parent d1cfea4e86d517177ced89eb96f7f51aa9200298
Author: Enno Boland (Gottox) <[email protected]>
Date: Fri, 5 Jun 2009 20:16:10 +0200
supporting multiple windows per instance
Diffstat:
M Makefile | 10 ++++++----
M surf.c | 196 +++++++++++++++++++----------…
2 files changed, 127 insertions(+), 79 deletions(-)
---
diff --git a/Makefile b/Makefile
t@@ -3,10 +3,10 @@
include config.mk
-SRC = surf.c
+SRC = surf.c tabbed.c
OBJ = ${SRC:.c=.o}
-all: options surf
+all: options surf tabbed
options:
@echo surf build options:
t@@ -20,9 +20,11 @@ options:
${OBJ}: config.mk
-surf: ${OBJ}
+surf: surf.o
@echo CC -o $@
- @${CC} -o $@ ${OBJ} ${LDFLAGS}
+ @${CC} -o $@ surf.o ${LDFLAGS}
+
+tabbed: tabbed.o
clean:
@echo cleaning
diff --git a/surf.c b/surf.c
t@@ -1,3 +1,7 @@
+/* See LICENSE file for copyright and license details.
+ *
+ * To understand surf, start reading main().
+ */
#include <X11/X.h>
#include <X11/Xatom.h>
#include <gtk/gtk.h>
t@@ -24,36 +28,48 @@
Display *dpy;
Atom urlprop;
-GtkWidget *win;
-GtkWidget *browser;
-WebKitWebView *view;
-gchar *title;
-gint progress = 100;
+typedef struct Client {
+ GtkWidget *win;
+ GtkWidget *browser;
+ WebKitWebView *view;
+ gchar *title;
+ gint progress;
+ struct Client *next;
+} Client;
+Client *clients = NULL;
gboolean embed = FALSE;
gboolean showxid = FALSE;
gboolean ignore_once = FALSE;
+static Client *newclient();
+static void die(char *str);
static void setup(void);
static void cleanup(void);
-static void updatetitle(void);
+static void updatetitle(Client *c);
static void windestroy(GtkWidget* w, gpointer d);
static gboolean keypress(GtkWidget* w, GdkEventKey *ev);
static void titlechange(WebKitWebView* view, WebKitWebFrame* frame, const gcha…
static void progresschange(WebKitWebView *view, gint p, gpointer d);
static void loadcommit(WebKitWebView *view, WebKitWebFrame *f, gpointer d);
static void linkhover(WebKitWebView* page, const gchar* t, const gchar* l, gpo…
+static void destroyclient(Client *c);
static gboolean newwindow(WebKitWebView *view, WebKitWebFrame *f,
WebKitNetworkRequest *r, WebKitWebNavigationAction *n,
WebKitWebPolicyDecision *p, gpointer d);
static gboolean download(WebKitWebView *view, GObject *o, gpointer d);
-static void loaduri(gchar *uri);
-static void loadfile(gchar *f);
-static void setupx();
+static void loaduri(const Client *c, const gchar *uri);
+static void loadfile(const Client *c, const gchar *f);
GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, gpointer data);
+void
+cleanup(void) {
+
+}
+
GdkFilterReturn
-processx(GdkXEvent *e, GdkEvent *event, gpointer data) {
+processx(GdkXEvent *e, GdkEvent *event, gpointer d) {
XPropertyEvent *ev;
+ Client *c = (Client *)d;
Atom adummy;
int idummy;
unsigned long ldummy;
t@@ -62,8 +78,8 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer data) {
ev = &((XEvent *)e)->xproperty;
if(ignore_once == FALSE && ev->atom == urlprop && ev->state ==…
XGetWindowProperty(dpy, ev->window, urlprop, 0L, BUFSI…
- &adummy, &idummy, &ldummy, &ldummy, &buf);
- loaduri((gchar *)buf);
+ &adummy, &idummy, &ldummy, &ldummy, &buf);
+ loaduri(c, (gchar *)buf);
XFree(buf);
return GDK_FILTER_REMOVE;
}
t@@ -73,45 +89,36 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer data) {
}
void
-setupx() {
- dpy = GDK_WINDOW_XDISPLAY(GTK_WIDGET(win)->window);
- urlprop = XInternAtom(dpy, "_SURF_URL", False);
- gdk_window_add_filter(GTK_WIDGET(win)->window, processx, NULL);
- gdk_window_set_events(GTK_WIDGET(win)->window, GDK_ALL_EVENTS_MASK);
-}
-
-void
-loadfile(gchar *f) {
- GIOChannel *c = NULL;
+loadfile(const Client *c, const gchar *f) {
+ GIOChannel *chan = NULL;
GError *e = NULL;
GString *code = g_string_new("");
GString *uri = g_string_new(f);
gchar *line;
if(strcmp(f, "-") == 0) {
- c = g_io_channel_unix_new(STDIN_FILENO);
- if (c) {
- while(g_io_channel_read_line(c, &line, NULL, NULL, &e)…
+ chan = g_io_channel_unix_new(STDIN_FILENO);
+ if (chan) {
+ while(g_io_channel_read_line(chan, &line, NULL, NULL, …
g_string_append(code, line);
g_free(line);
}
- webkit_web_view_load_html_string(view, code->str, NULL…
- g_free(code);
- g_io_channel_shutdown(c, FALSE, NULL);
+ webkit_web_view_load_html_string(c->view, code->str, N…
+ g_io_channel_shutdown(chan, FALSE, NULL);
}
}
else {
g_string_prepend(uri, "file://");
- loaduri(uri->str);
+ loaduri(c, uri->str);
}
}
-static void loaduri(gchar *uri) {
+static void loaduri(const Client *c, const gchar *uri) {
GString* u = g_string_new(uri);
- if(g_strrstr(u->str, "://") == NULL)
+ if(g_strrstr(u->str, ":") == NULL)
g_string_prepend(u, "http://");
- webkit_web_view_load_uri(view, u->str);
+ webkit_web_view_load_uri(c->view, u->str);
g_string_free(u, TRUE);
}
t@@ -125,8 +132,9 @@ gboolean
newwindow(WebKitWebView *view, WebKitWebFrame *f,
WebKitNetworkRequest *r, WebKitWebNavigationAction *n,
WebKitWebPolicyDecision *p, gpointer d) {
- /* TODO */
- return FALSE;
+ Client *c = newclient();
+ webkit_web_view_load_request(c->view, r);
+ return TRUE;
}
void
linkhover(WebKitWebView* page, const gchar* t, const gchar* l, gpointer d) {
t@@ -135,43 +143,64 @@ linkhover(WebKitWebView* page, const gchar* t, const gch…
void
loadcommit(WebKitWebView *view, WebKitWebFrame *f, gpointer d) {
+ Client *c = (Client *)d;
gchar *uri;
if(!(uri = (gchar *)webkit_web_view_get_uri(view)))
uri = "(null)";
ignore_once = TRUE;
- XChangeProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(win)->window), urlprop,
+ XChangeProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(c->win)->window), urlpr…
XA_STRING, 8, PropModeReplace, (unsigned char *)uri,
strlen(uri) + 1);
}
void
progresschange(WebKitWebView* view, gint p, gpointer d) {
- progress = p;
- updatetitle();
+ Client *c = (Client *)d;
+
+ c->progress = p;
+ updatetitle(c);
}
void
-updatetitle() {
+updatetitle(Client *c) {
char t[512];
- if(progress == 100)
- snprintf(t, LENGTH(t), "%s", title);
+ if(c->progress == 100)
+ snprintf(t, LENGTH(t), "%s", c->title);
else
- snprintf(t, LENGTH(t), "%s [%i%%]", title, progress);
- gtk_window_set_title(GTK_WINDOW(win), t);
+ snprintf(t, LENGTH(t), "%s [%i%%]", c->title, c->progress);
+ gtk_window_set_title(GTK_WINDOW(c->win), t);
}
void
titlechange(WebKitWebView *v, WebKitWebFrame *f, const gchar *t, gpointer d) {
- if(title)
- g_free(title);
- title = g_strdup(t);
- updatetitle();
+ Client *c = (Client *)d;
+
+ if(c->title)
+ g_free(c->title);
+ c->title = g_strdup(t);
+ updatetitle(c);
}
void
windestroy(GtkWidget* w, gpointer d) {
- gtk_main_quit();
+ Client *c = (Client *)d;
+
+ destroyclient(c);
+}
+
+void
+destroyclient(Client *c) {
+ Client *p;
+ gtk_widget_destroy(c->win);
+ if(clients == c && c->next == NULL)
+ gtk_main_quit();
+ for(p = clients; p && p->next != c; p = p->next);
+ if(p)
+ p->next = c->next;
+ else
+ clients = c->next;
+ free(c);
}
gboolean
t@@ -181,43 +210,60 @@ keypress(GtkWidget* w, GdkEventKey *ev) {
}
void setup(void) {
+ dpy = GDK_DISPLAY();
+ urlprop = XInternAtom(dpy, "_SURF_URL", False);
+}
+
+void die(char *str) {
+ fputs(str, stderr);
+ exit(EXIT_FAILURE);
+}
+
+Client *
+newclient(void) {
+ Client *c;
+ if(!(c = calloc(1, sizeof(Client))))
+ die("Cannot malloc!\n");
if(embed) {
- win = gtk_plug_new(0);
+ c->win = gtk_plug_new(0);
}
else {
- win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_wmclass(GTK_WINDOW(win), "surf", "surf");
+ c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "surf");
}
- gtk_window_set_default_size(GTK_WINDOW(win), 800, 600);
- browser = gtk_scrolled_window_new(NULL, NULL);
- g_signal_connect (G_OBJECT(win), "destroy", G_CALLBACK(windestroy), NU…
- g_signal_connect (G_OBJECT(win), "key-press-event", G_CALLBACK(keypres…
+ gtk_window_set_default_size(GTK_WINDOW(c->win), 800, 600);
+ c->browser = gtk_scrolled_window_new(NULL, NULL);
+ g_signal_connect (G_OBJECT(c->win), "destroy", G_CALLBACK(windestroy),…
+ g_signal_connect (G_OBJECT(c->win), "key-press-event", G_CALLBACK(keyp…
- gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(browser),
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(c->browser),
GTK_POLICY_NEVER, GTK_POLICY_NEVER);
- view = WEBKIT_WEB_VIEW(webkit_web_view_new());
- gtk_container_add(GTK_CONTAINER(browser), GTK_WIDGET(view));
+ c->view = WEBKIT_WEB_VIEW(webkit_web_view_new());
+ gtk_container_add(GTK_CONTAINER(c->browser), GTK_WIDGET(c->view));
- g_signal_connect(G_OBJECT(view), "title-changed", G_CALLBACK(titlechan…
- g_signal_connect(G_OBJECT(view), "load-progress-changed", G_CALLBACK(p…
- g_signal_connect(G_OBJECT(view), "load-committed", G_CALLBACK(loadcomm…
- g_signal_connect(G_OBJECT(view), "hovering-over-link", G_CALLBACK(link…
- g_signal_connect(G_OBJECT(view), "new-window-policy-decision-requested…
- g_signal_connect(G_OBJECT(view), "download-requested", G_CALLBACK(down…
- /* g_signal_connect(G_OBJECT(view), "create-web-view", G_CALLBACK(crea…
+ g_signal_connect(G_OBJECT(c->view), "title-changed", G_CALLBACK(titlec…
+ g_signal_connect(G_OBJECT(c->view), "load-progress-changed", G_CALLBAC…
+ g_signal_connect(G_OBJECT(c->view), "load-committed", G_CALLBACK(loadc…
+ g_signal_connect(G_OBJECT(c->view), "hovering-over-link", G_CALLBACK(l…
+ g_signal_connect(G_OBJECT(c->view), "new-window-policy-decision-reques…
+ g_signal_connect(G_OBJECT(c->view), "download-requested", G_CALLBACK(d…
+ /* g_signal_connect(G_OBJECT(c->view), "create-web-view", G_CALLBACK(c…
- gtk_container_add(GTK_CONTAINER(win), browser);
- gtk_widget_grab_focus(GTK_WIDGET(view));
- gtk_widget_show_all(win);
+ gtk_container_add(GTK_CONTAINER(c->win), c->browser);
+ gtk_widget_grab_focus(GTK_WIDGET(c->view));
+ gtk_widget_show_all(c->win);
if(showxid)
- printf("%u\n", (unsigned int)GDK_WINDOW_XID(GTK_WIDGET(win)->w…
-}
-
-void cleanup() {
+ printf("%u\n", (unsigned int)GDK_WINDOW_XID(GTK_WIDGET(c->win)…
+ c->next = clients;
+ clients = c;
+ gdk_window_set_events(GTK_WIDGET(c->win)->window, GDK_ALL_EVENTS_MASK);
+ gdk_window_add_filter(GTK_WIDGET(c->win)->window, processx, c);
+ return c;
}
int main(int argc, char *argv[]) {
gchar *uri = NULL, *file = NULL;
+ Client *c;
ARG {
case 'x':
t@@ -247,12 +293,12 @@ int main(int argc, char *argv[]) {
if (!g_thread_supported())
g_thread_init(NULL);
setup();
- setupx();
+ c = newclient();
if(uri)
- loaduri(uri);
+ loaduri(c, uri);
else if(file)
- loadfile(file);
- updatetitle();
+ loadfile(c, file);
+ updatetitle(c);
gtk_main();
cleanup();
return EXIT_SUCCESS;
You are viewing proxied material from mx1.adamsgaard.dk. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.