52 Commits

Author SHA1 Message Date
Enno Boland (tox) ca1c7f434b Adding Nibbles patch 2010-05-28 13:20:17 +02:00
Enno Boland (tox) 8cc71f8216 typo 2010-05-26 15:34:09 +02:00
Enno Boland (tox) 7330d0e261 Applying Nibbles download patch. Thanks! 2010-05-26 15:33:01 +02:00
Enno Boland (tox) 7d3d996a3d merge 2010-05-25 10:38:23 +02:00
Enno Boland (tox) d46697044e changing user agent string as suggested by Marvin Vek 2010-05-25 10:34:43 +02:00
Enno Boland (tox) 532205d7e7 removing spatial navigation. 2010-05-24 21:35:20 +02:00
Enno Boland (tox) aadcd5b3f0 implementing downloading. 2010-05-24 21:23:39 +02:00
Enno Boland (tox) 7fcf745092 enabling spatial-navigation 2010-05-24 21:23:28 +02:00
Enno Boland (tox) 5878067225 AtomHiLight is set correctly for links. 2010-05-18 14:20:24 +02:00
Enno Boland (tox) 7ce2856194 merge 2010-05-17 23:13:44 +02:00
Enno Boland (tox) 36129338cf changing xprops 2010-05-17 11:45:28 +02:00
Enno Boland (tox) 0a6eafe077 dl is not needed anymore 2010-05-17 11:01:37 +02:00
Enno Boland (tox) 6376a30379 removing context-menu, downloading. 2010-05-17 10:58:08 +02:00
Enno Boland (tox) 3dbf628964 changing sessiontime to 3600 2010-05-15 15:47:47 +02:00
Enno Boland (tox) 91d04b15f0 merge 2010-05-11 14:57:44 +02:00
Enno Boland (tox) b1e9a6e9ab fix download/history bug 2010-05-11 14:57:09 +02:00
pancake 424936e96c Fix NOBACKGROUND meaning 2010-05-09 22:51:26 +02:00
Enno Boland (tox) 8acc31bbde changing default value of NOBACKGROUND 2010-05-09 22:46:22 +02:00
Enno Boland (tox) f304d0af52 merge 2010-05-09 22:41:11 +02:00
Enno Boland (tox) 168da3730f added js-fix by Troels Henriksen. Thanks :) 2010-05-09 19:37:46 +02:00
pancake 11039e5e2b Do not set cookie session time if set to 0
Add NOBACKGROUND config.def.h option
 - requires body {background-color} in style.css
 - fixes white background when loading pages
2010-05-08 21:43:53 +02:00
Enno Boland (tox) 602eb61623 implementing naive file locking. 2010-05-06 13:58:49 +02:00
Enno Boland (tox) bef892f513 fixing compilerwarning in newer webkit versions 2010-05-06 13:09:54 +02:00
Enno Boland (tox) f9a411f22d fixing config.mk 2010-05-06 13:06:50 +02:00
Enno Boland (tox) e9c9715f52 Adding small fix by Alex Puterbaugh. Thanks. 2010-05-02 10:59:28 +02:00
pancake 4b1b1b8a20 remove empty lines 2010-04-08 20:28:32 +02:00
Enno Boland (tox) 8aabfa5b45 whoops... linking Oo 2010-03-29 17:49:34 +02:00
Enno Boland (tox) 981e52d5a7 typofix. 2010-03-26 21:44:48 +01:00
Enno Boland (tox) a7f2765da4 reimplementing cookies. Now we need some file locking. 2010-03-25 09:59:30 +01:00
Enno Boland (tox) a05bcc653e updating manpage, reformating help output. 2010-03-25 00:05:37 +01:00
Enno Boland (tox) 62dc599a04 fixing argument parsing. 2010-03-24 23:55:41 +01:00
Enno Boland (tox) 3ede103556 fixing downloads 2010-03-24 23:18:03 +01:00
Enno Boland (tox) 19aaa5a74b gotheaders will now be called correctly. 2010-03-24 22:04:36 +01:00
Enno Boland (tox) 3434ccc16a adding surf-logo. 2010-03-24 21:05:11 +01:00
Enno Boland (tox) b8105c64ed working on cookies 2010-03-24 20:56:56 +01:00
Enno Boland (tox) e2cae4d1f5 reformating 2010-03-24 19:16:10 +01:00
Enno Boland (tox) 814bf92565 adding cmd-switches for turning of images/plugins/scripts 2010-03-24 19:11:01 +01:00
Enno Boland (tox) e252a5ec63 now we've got access to cookies before they're sended. Let's start building a cookiehandler. 2010-03-24 18:17:19 +01:00
Enno Boland (tox) b2a970d04d session gets set properly in setup() 2010-03-10 21:38:07 +01:00
Enno Boland (tox) 1cbeab188d fixing progress, beginning new cookie implementation 2010-03-08 10:06:32 +01:00
Enno Boland (tox) 764550e087 small typo. 2010-03-08 09:30:26 +01:00
Enno Boland (tox) 4f7fdd1dfa removed persistent cookies, replaced deprecated eventlisteners 2010-03-08 09:24:55 +01:00
Enno Boland (tox) 94601622a1 _SURF_URI gets initialised as soon as the window opens. 2010-01-29 09:44:14 +01:00
Enno Boland (tox) b18189d016 fixing manpage 2010-01-20 14:46:22 +01:00
Enno Boland (tox) 0fb97666ec dl has to be a directory, not a file. 2010-01-04 14:39:40 +01:00
Enno Boland (tox) 2f9c554f02 adding fixes from thomas_adam. Thanks :) 2009-12-15 17:16:01 +01:00
Enno Boland (tox) f42461c3cc Backed out changeset 260fda70689f 2009-11-09 00:05:45 +01:00
Enno Boland (tox) 1d93bfa9ce changing locking algorythm for setprop. 2009-11-08 23:45:36 +01:00
Enno Boland (tox) b57eca1a2b SETPROP() macro shows now the current value in dwm. 2009-11-08 23:45:11 +01:00
Enno Boland (tox) c0510b0cc9 next version will be 0.4 2009-11-02 09:29:54 +01:00
Enno Boland (tox) f0f3ddce76 adding environment variables for proxy and useragent 2009-11-02 09:27:32 +01:00
Enno Boland (tox) 7365214bbf Added tag 0.3 for changeset 46d516fd2167 2009-10-30 13:40:49 +01:00
6 changed files with 263 additions and 258 deletions
+1
View File
@@ -4,3 +4,4 @@ d8628fc93353faa411c9fc7eef82d11a84d26ae2 0.1
3ef997607115303fe93873b592d152f0ec186f77 0.1.1
bffb0c3c23410ac7f260d167f4b9771497fc1127 0.1.2
a5db79d487c85615be2ecf30815c6b4977e88000 0.2
46d516fd216731adf91740496e6823c1be4f6199 0.3
+13 -20
View File
@@ -1,17 +1,21 @@
/* modifier 0 means no modifier */
static char *useragent = "Mozilla/5.0 (X11; U; Linux; en-us) AppleWebKit/531.2+ (KHTML, like Gecko, surf-"VERSION") Safari/531.2+";
static char *useragent = "Surf/"VERSION" (X11; U; Unix; en-US) AppleWebKit/531.2+ Compatible (Safari)";
static char *progress = "#FF0000";
static char *progress_trust = "#00FF00";
static char *stylefile = ".surf/style.css";
static char *scriptfile = ".surf/script.js";
static char *cookiefile = ".surf/cookies.txt";
static char *dldir = ".surf/dl";
static time_t sessiontime = 3600;
static time_t sessiontime = 0;
#define NOBACKGROUND 0
#define SETPROP(p) { .v = (char *[]){ "/bin/sh", "-c", \
"prop=\"`dmenu < /dev/null`\" &&" \
"xprop -id $1 -f $0 8s -set $0 \"$prop\"", \
p, winid, NULL } }
#define SETPROP(p, q) { .v = (char *[]){ "/bin/sh", "-c", \
"prop=\"`xprop -id $2 $0 | cut -d '\"' -f 2 | dmenu`\" &&" \
"xprop -id $2 -f $1 8s -set $1 \"$prop\"", \
p, q, winid, NULL } }
#define DOWNLOAD(d) { \
.v = (char *[]){ "/bin/sh", "-c", \
"xterm -e \"wget --load-cookies ~/.surf/cookies.txt '$0';\"", \
d, NULL } }
#define MODKEY GDK_CONTROL_MASK
static Key keys[] = {
/* modifier keyval function arg Focus */
@@ -29,19 +33,8 @@ static Key keys[] = {
{ MODKEY, GDK_k, scroll, { .i = -1 } },
{ 0, GDK_Escape, stop, { 0 } },
{ MODKEY, GDK_o, source, { 0 } },
{ MODKEY, GDK_g, spawn, SETPROP("_SURF_URI") },
{ MODKEY, GDK_slash, spawn, SETPROP("_SURF_FIND") },
{ MODKEY, GDK_g, spawn, SETPROP("_SURF_URI", "_SURF_GO") },
{ MODKEY, GDK_slash, spawn, SETPROP("_SURF_FIND", "_SURF_FIND") },
{ MODKEY, GDK_n, find, { .b = TRUE } },
{ MODKEY|GDK_SHIFT_MASK,GDK_n, find, { .b = FALSE } },
};
static Item items[] = {
{ "Back", navigate, { .i = -1 } },
{ "Forward", navigate, { .i = +1 } },
{ "New Window", newwindow, { .v = NULL } },
{ "Reload", reload, { .b = FALSE } },
{ "Stop", stop, { 0 } },
{ "Paste URI", clipboard, { .b = TRUE } },
{ "Copy URI", clipboard, { .b = FALSE } },
{ "Download", download, { 0 } },
};
+2 -2
View File
@@ -1,5 +1,5 @@
# surf version
VERSION = 0.3
VERSION = 0.4
# Customize below to fit your system
@@ -18,7 +18,7 @@ LIBS = -L/usr/lib -lc ${GTKLIB} -lgthread-2.0
# flags
CPPFLAGS = -DVERSION=\"${VERSION}\"
CFLAGS = -std=c99 -pedantic -Wall -Os ${INCS} ${CPPFLAGS}
LDFLAGS = -s ${LIBS}
LDFLAGS = -g ${LIBS}
# Solaris
#CFLAGS = -fast ${INCS} -DVERSION=\"${VERSION}\"
+24 -6
View File
@@ -3,7 +3,12 @@
surf \- simple webkit-based browser
.SH SYNOPSIS
.B surf
.RB [ \-ehvx ]
.RB [-e\ xid]
.RB [-i]
.RB [-p]
.RB [-s]
.RB [-v]
.RB [-x]
.RB "URI"
.SH DESCRIPTION
surf is a simple Web browser based on WebKit/GTK+. It is able
@@ -12,12 +17,17 @@ which makes it possible to embed it in another application. Furthermore,
one can point surf to another URI by setting its XProperties.
.SH OPTIONS
.TP
.B \-e
Prints xid to standard output and waits until an application reparents the
window.
.B \-e xid
Reparents to window specified by xid.
.TP
.B \-h
Prints usage information to standard output, then exits.
.B \-i
Disable Images
.TP
.B \-p
Disable Plugins
.TP
.B \-s
Disable Javascript
.TP
.B \-v
Prints version information to standard output, then exits.
@@ -26,6 +36,8 @@ Prints version information to standard output, then exits.
Prints xid to standard output. This can be used to script the browser by using
.BR xprop(1).
.SH USAGE
.B Escape
Stops loading current page or stops download.
.TP
.B Ctrl\-h
Walks back the history.
@@ -51,6 +63,12 @@ Resets Zoom
.B Ctrl\-/
Opens the search-bar.
.TP
.B Ctrl\-n
Go to next search result.
.TP
.B Ctrl\-Shift\-n
Go to previous search result.
.TP
.B Ctrl\-g
Opens the URL-bar.
.TP
+223 -230
View File
@@ -18,10 +18,13 @@
#include <webkit/webkit.h>
#include <glib/gstdio.h>
#include <JavaScriptCore/JavaScript.h>
#include <sys/file.h>
#define LENGTH(x) (sizeof x / sizeof x[0])
#define CLEANMASK(mask) (mask & ~(GDK_MOD2_MASK))
enum { AtomFind, AtomGo, AtomUri, AtomLast };
typedef union Arg Arg;
union Arg {
gboolean b;
@@ -31,9 +34,7 @@ union Arg {
typedef struct Client {
GtkWidget *win, *scroll, *vbox, *indicator;
GtkWidget **items;
WebKitWebView *view;
WebKitDownload *download;
char *title, *linkhover;
const char *uri, *needle;
gint progress;
@@ -55,22 +56,17 @@ typedef struct {
} Key;
static Display *dpy;
static Atom uriprop, findprop;
static SoupCookieJar *cookies;
static SoupSession *session;
static Atom atoms[AtomLast];
static Client *clients = NULL;
static GdkNativeWindow embed = 0;
static gboolean showxid = FALSE;
static int ignorexprop = 0;
static char winid[64];
static char *progname;
static gboolean lockcookie = FALSE;
static gboolean loadimage = 1, plugin = 1, script = 1;
static char *buildpath(const char *path);
static void changecookie(SoupCookieJar *jar, SoupCookie *o, SoupCookie *n, gpointer p);
static void cleanup(void);
static void clipboard(Client *c, const Arg *arg);
static void context(WebKitWebView *v, GtkMenu *m, Client *c);
static char *copystr(char **str, const char *src);
static WebKitWebView *createwindow(WebKitWebView *v, WebKitWebFrame *f, Client *c);
static gboolean decidedownload(WebKitWebView *v, WebKitWebFrame *f, WebKitNetworkRequest *r, gchar *m, WebKitWebPolicyDecision *p, Client *c);
@@ -78,31 +74,31 @@ static gboolean decidewindow(WebKitWebView *v, WebKitWebFrame *f, WebKitNetworkR
static void destroyclient(Client *c);
static void destroywin(GtkWidget* w, Client *c);
static void die(char *str);
static void download(Client *c, const Arg *arg);
static void drawindicator(Client *c);
static gboolean exposeindicator(GtkWidget *w, GdkEventExpose *e, Client *c);
static void find(Client *c, const Arg *arg);
static const char *getatom(Client *c, Atom a);
static const char *getatom(Client *c, int a);
static const char *getcookies(SoupURI *uri);
static char *geturi(Client *c);
void gotheaders(SoupMessage *msg, gpointer user_data);
static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c);
static void itemclick(GtkMenuItem *mi, Client *c);
static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c);
static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c);
static void loadcommit(WebKitWebView *v, WebKitWebFrame *f, Client *c);
static void loadstart(WebKitWebView *v, WebKitWebFrame *f, Client *c);
static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c);
static void loaduri(Client *c, const Arg *arg);
static void navigate(Client *c, const Arg *arg);
static Client *newclient(void);
static void newwindow(Client *c, const Arg *arg);
static void newrequest(SoupSession *s, SoupMessage *msg, gpointer v);
static void pasteuri(GtkClipboard *clipboard, const char *text, gpointer d);
static void print(Client *c, const Arg *arg);
static GdkFilterReturn processx(GdkXEvent *xevent, GdkEvent *event, gpointer d);
static void progresschange(WebKitWebView *v, gint p, Client *c);
static void progresschange(WebKitWebView *view, GParamSpec *pspec, Client *c);
static void reload(Client *c, const Arg *arg);
static void reloadcookies();
static void resize(GtkWidget *w, GtkAllocation *a, Client *c);
static void scroll(Client *c, const Arg *arg);
static void setatom(Client *c, Atom a, const char *v);
static void setatom(Client *c, int a, const char *v);
static void setcookie(SoupCookie *c);
static void setup(void);
static void sigchld(int unused);
static void source(Client *c, const Arg *arg);
@@ -110,7 +106,6 @@ static void spawn(Client *c, const Arg *arg);
static void stop(Client *c, const Arg *arg);
static void titlechange(WebKitWebView *v, WebKitWebFrame* frame, const char* title, Client *c);
static void update(Client *c);
static void updatedownload(WebKitDownload *o, GParamSpec *pspec, Client *c);
static void updatewinid(Client *c);
static void usage(void);
static void windowobjectcleared(GtkWidget *w, WebKitWebFrame *frame, JSContextRef js, JSObjectRef win, Client *c);
@@ -135,42 +130,33 @@ buildpath(const char *path) {
*p = '/';
}
/* creating file (gives error when apath ends with "/") */
if((f = g_fopen(apath, "a")))
if((f = fopen(apath, "a")))
fclose(f);
return apath;
}
void
changecookie(SoupCookieJar *j, SoupCookie *oc, SoupCookie *c, gpointer p) {
SoupDate *e;
SoupCookieJar *jar;
if(lockcookie)
return;
if(c && c->expires == NULL) {
e = soup_date_new_from_time_t(time(NULL) + sessiontime);
c = soup_cookie_copy(c);
soup_cookie_set_expires(c, e);
}
jar = soup_cookie_jar_text_new(cookiefile, FALSE);
if(c)
soup_cookie_jar_add_cookie(jar, soup_cookie_copy(c));
else
soup_cookie_jar_delete_cookie(jar, oc);
g_object_unref(jar);
}
void
cleanup(void) {
while(clients)
destroyclient(clients);
g_free(cookiefile);
g_free(dldir);
g_free(scriptfile);
g_free(stylefile);
}
void
runscript(WebKitWebFrame *frame, JSContextRef js) {
JSStringRef jsscript;
char *script;
JSValueRef exception = NULL;
GError *error;
if(g_file_get_contents(scriptfile, &script, NULL, &error)) {
jsscript = JSStringCreateWithUTF8CString(script);
JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), NULL, 0, &exception);
}
}
void
clipboard(Client *c, const Arg *arg) {
gboolean paste = *(gboolean *)arg;
@@ -181,22 +167,6 @@ clipboard(Client *c, const Arg *arg) {
gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), c->linkhover ? c->linkhover : geturi(c), -1);
}
void
context(WebKitWebView *v, GtkMenu *m, Client *c) {
int i;
GtkContainer *parent;
gtk_widget_hide_all(GTK_WIDGET(m));
gtk_widget_show(GTK_WIDGET(m));
for(i = 0; i < LENGTH(items); i++) {
parent = GTK_CONTAINER(gtk_widget_get_parent(c->items[i]));
if(parent)
gtk_container_remove(parent, c->items[i]);
gtk_menu_shell_append(GTK_MENU_SHELL(m), c->items[i]);
gtk_widget_show(c->items[i]);
}
}
char *
copystr(char **str, const char *src) {
char *tmp;
@@ -239,7 +209,6 @@ decidewindow(WebKitWebView *view, WebKitWebFrame *f, WebKitNetworkRequest *r, We
void
destroyclient(Client *c) {
int i;
Client *p;
gtk_widget_destroy(c->indicator);
@@ -247,9 +216,6 @@ destroyclient(Client *c) {
gtk_widget_destroy(c->scroll);
gtk_widget_destroy(c->vbox);
gtk_widget_destroy(c->win);
for(i = 0; i < LENGTH(items); i++)
gtk_widget_destroy(c->items[i]);
free(c->items);
for(p = clients; p && p->next != c; p = p->next);
if(p)
@@ -272,21 +238,6 @@ die(char *str) {
exit(EXIT_FAILURE);
}
void
download(Client *c, const Arg *arg) {
char *uri;
WebKitNetworkRequest *r;
WebKitDownload *dl;
if(arg->v)
uri = (char *)arg->v;
else
uri = c->linkhover ? c->linkhover : geturi(c);
r = webkit_network_request_new(uri);
dl = webkit_download_new(r);
initdownload(c->view, dl, c);
}
void
drawindicator(Client *c) {
gint width;
@@ -295,7 +246,7 @@ drawindicator(Client *c) {
GdkGC *gc;
GdkColor fg;
uri = getatom(c, uriprop);
uri = geturi(c);
w = c->indicator;
width = c->progress * w->allocation.width / 100;
gc = gdk_gc_new(w->window);
@@ -320,13 +271,22 @@ void
find(Client *c, const Arg *arg) {
const char *s;
s = getatom(c, findprop);
s = getatom(c, AtomFind);
gboolean forward = *(gboolean *)arg;
webkit_web_view_search_text(c->view, s, FALSE, forward, TRUE);
}
const char *
getatom(Client *c, Atom a) {
getcookies(SoupURI *uri) {
const char *c;
SoupCookieJar *j = soup_cookie_jar_text_new(cookiefile, TRUE);
c = soup_cookie_jar_get_cookies(j, uri, TRUE);
g_object_unref(j);
return c;
}
const char *
getatom(Client *c, int a) {
static char buf[BUFSIZ];
Atom adummy;
int idummy;
@@ -334,7 +294,7 @@ getatom(Client *c, Atom a) {
unsigned char *p = NULL;
XGetWindowProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(c->win)->window),
a, 0L, BUFSIZ, False, XA_STRING,
atoms[a], 0L, BUFSIZ, False, XA_STRING,
&adummy, &idummy, &ldummy, &ldummy, &p);
if(p)
strncpy(buf, (char *)p, LENGTH(buf)-1);
@@ -353,42 +313,27 @@ geturi(Client *c) {
return uri;
}
gboolean
initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
const char *filename;
char *uri, *html;
void
gotheaders(SoupMessage *msg, gpointer v) {
SoupURI *uri;
GSList *l, *p;
stop(c, NULL);
c->download = o;
filename = webkit_download_get_suggested_filename(o);
if(!strcmp("", filename))
filename = "index.html";
uri = g_strconcat("file://", dldir, "/", filename, NULL);
webkit_download_set_destination_uri(c->download, uri);
c->progress = 0;
g_free(uri);
html = g_strdup_printf("Download <b>%s</b>...", filename);
webkit_web_view_load_html_string(c->view, html,
webkit_download_get_uri(c->download));
g_signal_connect(c->download, "notify::progress", G_CALLBACK(updatedownload), c);
g_signal_connect(c->download, "notify::status", G_CALLBACK(updatedownload), c);
webkit_download_start(c->download);
c->title = copystr(&c->title, filename);
update(c);
g_free(html);
return TRUE;
uri = soup_message_get_uri(msg);
for(p = l = soup_cookies_from_response(msg); p;
p = g_slist_next(p)) {
setcookie((SoupCookie *)p->data);
}
soup_cookies_free(l);
}
void
itemclick(GtkMenuItem *mi, Client *c) {
int i;
const char *label;
gboolean
initdownload(WebKitWebView *view, WebKitDownload *o, Client *c) {
Arg arg;
label = gtk_menu_item_get_label(mi);
for(i = 0; i < LENGTH(items); i++)
if(!strcmp(items[i].label, label))
items[i].func(c, &(items[i].arg));
updatewinid(c);
arg = (Arg)DOWNLOAD((char *)webkit_download_get_uri(o));
spawn(c, &arg);
return FALSE;
}
gboolean
@@ -410,8 +355,9 @@ keypress(GtkWidget* w, GdkEventKey *ev, Client *c) {
void
linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
if(l)
if(l) {
c->linkhover = copystr(&c->linkhover, l);
}
else if(c->linkhover) {
free(c->linkhover);
c->linkhover = NULL;
@@ -420,44 +366,56 @@ linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
}
void
loadcommit(WebKitWebView *view, WebKitWebFrame *f, Client *c) {
setatom(c, uriprop, geturi(c));
}
void
loadstart(WebKitWebView *view, WebKitWebFrame *f, Client *c) {
c->progress = 0;
update(c);
reloadcookies();
loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c) {
switch(webkit_web_view_get_load_status (c->view)) {
case WEBKIT_LOAD_COMMITTED:
setatom(c, AtomUri, geturi(c));
break;
case WEBKIT_LOAD_FINISHED:
c->progress = 0;
update(c);
break;
default:
break;
}
}
void
loaduri(Client *c, const Arg *arg) {
char *u;
const char *uri = (char *)arg->v;
Arg a = { .b = FALSE };
if(strcmp(uri, "") == 0)
return;
u = g_strrstr(uri, "://") ? g_strdup(uri)
: g_strdup_printf("http://%s", uri);
webkit_web_view_load_uri(c->view, u);
c->progress = 0;
c->title = copystr(&c->title, u);
g_free(u);
update(c);
/* prevents endless loop */
if(c->uri && strcmp(u, c->uri) == 0) {
reload(c, &a);
}
else {
webkit_web_view_load_uri(c->view, u);
c->progress = 0;
c->title = copystr(&c->title, u);
g_free(u);
update(c);
}
}
void
navigate(Client *c, const Arg *arg) {
gint steps = *(gint *)arg;
int steps = *(int *)arg;
webkit_web_view_go_back_or_forward(c->view, steps);
}
Client *
newclient(void) {
int i;
Client *c;
WebKitWebSettings *settings;
WebKitWebFrame *frame;
GdkGeometry hints = { 1, 1 };
char *uri;
char *uri, *ua;
if(!(c = calloc(1, sizeof(Client))))
die("Cannot malloc!\n");
@@ -467,23 +425,25 @@ newclient(void) {
}
else {
c->win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
/* TA: 20091214: Despite what the GNOME docs say, the ICCCM
* is always correct, so we should still call this function.
* But when doing so, we *must* differentiate between a
* WM_CLASS and a resource on the window. By convention, the
* window class (WM_CLASS) is capped, while the resource is in
* lowercase. Both these values come as a pair.
*/
gtk_window_set_wmclass(GTK_WINDOW(c->win), "surf", "surf");
/* TA: 20091214: And set the role here as well -- so that
* sessions can pick this up.
*/
gtk_window_set_role(GTK_WINDOW(c->win), "Surf");
}
gtk_window_set_default_size(GTK_WINDOW(c->win), 800, 600);
g_signal_connect(G_OBJECT(c->win), "destroy", G_CALLBACK(destroywin), c);
g_signal_connect(G_OBJECT(c->win), "key-press-event", G_CALLBACK(keypress), c);
g_signal_connect(G_OBJECT(c->win), "size-allocate", G_CALLBACK(resize), c);
if(!(c->items = calloc(1, sizeof(GtkWidget *) * LENGTH(items))))
die("Cannot malloc!\n");
/* contextmenu */
for(i = 0; i < LENGTH(items); i++) {
c->items[i] = gtk_menu_item_new_with_label(items[i].label);
g_signal_connect(G_OBJECT(c->items[i]), "activate",
G_CALLBACK(itemclick), c);
}
/* VBox */
c->vbox = gtk_vbox_new(FALSE, 0);
@@ -495,16 +455,14 @@ newclient(void) {
/* Webview */
c->view = WEBKIT_WEB_VIEW(webkit_web_view_new());
g_signal_connect(G_OBJECT(c->view), "title-changed", G_CALLBACK(titlechange), c);
g_signal_connect(G_OBJECT(c->view), "load-progress-changed", G_CALLBACK(progresschange), c);
g_signal_connect(G_OBJECT(c->view), "load-committed", G_CALLBACK(loadcommit), c);
g_signal_connect(G_OBJECT(c->view), "load-started", G_CALLBACK(loadstart), c);
g_signal_connect(G_OBJECT(c->view), "hovering-over-link", G_CALLBACK(linkhover), c);
g_signal_connect(G_OBJECT(c->view), "create-web-view", G_CALLBACK(createwindow), c);
g_signal_connect(G_OBJECT(c->view), "new-window-policy-decision-requested", G_CALLBACK(decidewindow), c);
g_signal_connect(G_OBJECT(c->view), "mime-type-policy-decision-requested", G_CALLBACK(decidedownload), c);
g_signal_connect(G_OBJECT(c->view), "download-requested", G_CALLBACK(initdownload), c);
g_signal_connect(G_OBJECT(c->view), "window-object-cleared", G_CALLBACK(windowobjectcleared), c);
g_signal_connect(G_OBJECT(c->view), "populate-popup", G_CALLBACK(context), c);
g_signal_connect(G_OBJECT(c->view), "notify::load-status", G_CALLBACK(loadstatuschange), c);
g_signal_connect(G_OBJECT(c->view), "notify::progress", G_CALLBACK(progresschange), c);
g_signal_connect(G_OBJECT(c->view), "download-requested", G_CALLBACK(initdownload), c);
/* Indicator */
c->indicator = gtk_drawing_area_new();
@@ -531,14 +489,26 @@ newclient(void) {
gdk_window_set_events(GTK_WIDGET(c->win)->window, GDK_ALL_EVENTS_MASK);
gdk_window_add_filter(GTK_WIDGET(c->win)->window, processx, c);
webkit_web_view_set_full_content_zoom(c->view, TRUE);
frame = webkit_web_view_get_main_frame(c->view);
runscript(frame, webkit_web_frame_get_global_context(frame));
settings = webkit_web_view_get_settings(c->view);
g_object_set(G_OBJECT(settings), "user-agent", useragent, NULL);
if(!(ua = getenv("SURF_USERAGENT")))
ua = useragent;
g_object_set(G_OBJECT(settings), "user-agent", ua, NULL);
uri = g_strconcat("file://", stylefile, NULL);
g_object_set(G_OBJECT(settings), "user-stylesheet-uri", uri, NULL);
g_free(uri);
setatom(c, findprop, "");
g_object_set(G_OBJECT(settings), "auto-load-images", loadimage, NULL);
g_object_set(G_OBJECT(settings), "enable-plugins", plugin, NULL);
g_object_set(G_OBJECT(settings), "enable-scripts", script, NULL);
g_object_set(G_OBJECT(settings), "enable-spatial-navigation", true, NULL);
g_free(uri);
setatom(c, AtomFind, "");
setatom(c, AtomUri, "about:blank");
if(NOBACKGROUND)
webkit_web_view_set_transparent(c->view, TRUE);
c->download = NULL;
c->title = NULL;
c->next = clients;
clients = c;
@@ -550,10 +520,23 @@ newclient(void) {
return c;
}
void
newrequest(SoupSession *s, SoupMessage *msg, gpointer v) {
SoupMessageHeaders *h = msg->request_headers;
SoupURI *uri;
const char *c;
soup_message_headers_remove(h, "Cookie");
uri = soup_message_get_uri(msg);
if((c = getcookies(uri)))
soup_message_headers_append(h, "Cookie", c);
g_signal_connect_after(G_OBJECT(msg), "got-headers", G_CALLBACK(gotheaders), NULL);
}
void
newwindow(Client *c, const Arg *arg) {
guint i = 0;
const char *cmd[7], *uri;
const char *cmd[10], *uri;
const Arg a = { .v = (void *)cmd };
char tmp[64];
@@ -563,9 +546,14 @@ newwindow(Client *c, const Arg *arg) {
snprintf(tmp, LENGTH(tmp), "%u\n", (int)embed);
cmd[i++] = tmp;
}
if(showxid) {
if(!script)
cmd[i++] = "-s";
if(!plugin)
cmd[i++] = "-p";
if(!loadimage)
cmd[i++] = "-i";
if(showxid)
cmd[i++] = "-x";
}
cmd[i++] = "--";
uri = arg->v ? (char *)arg->v : c->linkhover;
if(uri)
@@ -594,26 +582,25 @@ processx(GdkXEvent *e, GdkEvent *event, gpointer d) {
if(((XEvent *)e)->type == PropertyNotify) {
ev = &((XEvent *)e)->xproperty;
if(ignorexprop)
ignorexprop--;
else if(ev->state == PropertyNewValue) {
if(ev->atom == uriprop) {
arg.v = getatom(c, uriprop);
loaduri(c, &arg);
}
else if(ev->atom == findprop) {
if(ev->state == PropertyNewValue) {
if(ev->atom == atoms[AtomFind]) {
arg.b = TRUE;
find(c, &arg);
return GDK_FILTER_REMOVE;
}
else if(ev->atom == atoms[AtomGo]) {
arg.v = getatom(c, AtomGo);
loaduri(c, &arg);
return GDK_FILTER_REMOVE;
}
return GDK_FILTER_REMOVE;
}
}
return GDK_FILTER_CONTINUE;
}
void
progresschange(WebKitWebView *v, gint p, Client *c) {
c->progress = p;
progresschange(WebKitWebView *view, GParamSpec *pspec, Client *c) {
c->progress = webkit_web_view_get_progress(c->view) * 100;
update(c);
}
@@ -626,23 +613,6 @@ reload(Client *c, const Arg *arg) {
webkit_web_view_reload(c->view);
}
void
reloadcookies() {
SoupCookieJar *jar;
GSList *l, *e;
lockcookie = TRUE;
for(l = e = soup_cookie_jar_all_cookies(cookies); e; e = e->next)
soup_cookie_jar_delete_cookie(cookies, (SoupCookie *)e->data);
soup_cookies_free(l);
jar = soup_cookie_jar_text_new(cookiefile, TRUE);
for(l = e = soup_cookie_jar_all_cookies(jar); e; e = e->next)
soup_cookie_jar_add_cookie(cookies, (SoupCookie *)e->data);
g_slist_free(l);
lockcookie = FALSE;
g_object_unref(jar);
}
void
resize(GtkWidget *w, GtkAllocation *a, Client *c) {
double zoom;
@@ -670,16 +640,37 @@ scroll(Client *c, const Arg *arg) {
}
void
setatom(Client *c, Atom a, const char *v) {
setcookie(SoupCookie *c) {
int lock;
lock = open(cookiefile, 0);
flock(lock, LOCK_EX);
SoupDate *e;
SoupCookieJar *j = soup_cookie_jar_text_new(cookiefile, FALSE);
c = soup_cookie_copy(c);
if(c->expires == NULL && sessiontime) {
e = soup_date_new_from_time_t(time(NULL) + sessiontime);
soup_cookie_set_expires(c, e);
}
soup_cookie_jar_add_cookie(j, c);
g_object_unref(j);
flock(lock, LOCK_UN);
close(lock);
}
void
setatom(Client *c, int a, const char *v) {
XSync(dpy, False);
ignorexprop++;
XChangeProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(c->win)->window), a,
XChangeProperty(dpy, GDK_WINDOW_XID(GTK_WIDGET(c->win)->window), atoms[a],
XA_STRING, 8, PropModeReplace, (unsigned char *)v,
strlen(v) + 1);
}
void
setup(void) {
char *proxy;
char *new_proxy;
SoupURI *puri;
SoupSession *s;
/* clean up any zombies immediately */
@@ -689,22 +680,33 @@ setup(void) {
g_thread_init(NULL);
dpy = GDK_DISPLAY();
session = webkit_get_default_session();
uriprop = XInternAtom(dpy, "_SURF_URI", False);
findprop = XInternAtom(dpy, "_SURF_FIND", False);
s = webkit_get_default_session();
/* create dirs and files */
/* atoms */
atoms[AtomFind] = XInternAtom(dpy, "_SURF_FIND", False);
atoms[AtomGo] = XInternAtom(dpy, "_SURF_GO", False);
atoms[AtomUri] = XInternAtom(dpy, "_SURF_URI", False);
/* dirs and files */
cookiefile = buildpath(cookiefile);
dldir = buildpath(dldir);
scriptfile = buildpath(scriptfile);
stylefile = buildpath(stylefile);
/* cookie persistance */
/* request handler */
s = webkit_get_default_session();
cookies = soup_cookie_jar_new();
soup_session_add_feature(s, SOUP_SESSION_FEATURE(cookies));
g_signal_connect(cookies, "changed", G_CALLBACK(changecookie), NULL);
reloadcookies();
soup_session_remove_feature_by_type(s, soup_cookie_get_type());
soup_session_remove_feature_by_type(s, soup_cookie_jar_get_type());
g_signal_connect_after(G_OBJECT(s), "request-started", G_CALLBACK(newrequest), NULL);
/* proxy */
if((proxy = getenv("http_proxy")) && strcmp(proxy, "")) {
new_proxy = g_strrstr(proxy, "http://") ? g_strdup(proxy) :
g_strdup_printf("http://%s", proxy);
puri = soup_uri_new(new_proxy);
g_object_set(G_OBJECT(s), "proxy-uri", puri, NULL);
soup_uri_free(puri);
g_free(new_proxy);
}
}
void
@@ -739,11 +741,7 @@ spawn(Client *c, const Arg *arg) {
void
stop(Client *c, const Arg *arg) {
if(c->download)
webkit_download_cancel(c->download);
else
webkit_web_view_stop_loading(c->view);
c->download = NULL;
webkit_web_view_stop_loading(c->view);
}
void
@@ -767,17 +765,6 @@ update(Client *c) {
g_free(t);
}
void
updatedownload(WebKitDownload *o, GParamSpec *pspec, Client *c) {
WebKitDownloadStatus status;
status = webkit_download_get_status(c->download);
if(status == WEBKIT_DOWNLOAD_STATUS_STARTED || status == WEBKIT_DOWNLOAD_STATUS_CREATED) {
c->progress = (gint)(webkit_download_get_progress(c->download)*100);
}
update(c);
}
void
updatewinid(Client *c) {
snprintf(winid, LENGTH(winid), "%u",
@@ -787,20 +774,12 @@ updatewinid(Client *c) {
void
usage(void) {
fputs("surf - simple browser\n", stderr);
die("usage: surf [-e Window] [-x] [uri]\n");
die("usage: surf [-e xid] [-i] [-p] [-s] [-v] [-x] [uri]\n");
}
void
windowobjectcleared(GtkWidget *w, WebKitWebFrame *frame, JSContextRef js, JSObjectRef win, Client *c) {
JSStringRef jsscript;
char *script;
JSValueRef exception = NULL;
GError *error;
if(g_file_get_contents(scriptfile, &script, NULL, &error)) {
jsscript = JSStringCreateWithUTF8CString(script);
JSEvaluateScript(js, jsscript, JSContextGetGlobalObject(js), NULL, 0, &exception);
}
runscript(frame, js);
}
void
@@ -816,29 +795,43 @@ zoom(Client *c, const Arg *arg) {
}
}
int main(int argc, char *argv[]) {
int
main(int argc, char *argv[]) {
int i;
Arg arg;
progname = argv[0];
/* command line args */
for(i = 1, arg.v = NULL; i < argc && argv[i][0] == '-'; i++) {
if(!strcmp(argv[i], "-x"))
showxid = TRUE;
else if(!strcmp(argv[i], "-e")) {
for(i = 1, arg.v = NULL; i < argc && argv[i][0] == '-' &&
argv[i][1] != '\0' && argv[i][2] == '\0'; i++) {
if(!strcmp(argv[i], "--")) {
i++;
break;
}
switch(argv[i][1]) {
case 'e':
if(++i < argc)
embed = atoi(argv[i]);
else
usage();
}
else if(!strcmp(argv[i], "--")) {
i++;
break;
}
else if(!strcmp(argv[i], "-v"))
case 'i':
loadimage = 0;
break;
case 'p':
plugin = 0;
break;
case 's':
script = 0;
break;
case 'x':
showxid = TRUE;
break;
case 'v':
die("surf-"VERSION", © 2009 surf engineers, see LICENSE for details\n");
else
default:
usage();
}
}
if(i < argc)
arg.v = argv[i];
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B