#include <JavaScriptCore/JavaScript.h>
#include <sys/file.h>
+#include "arg.h"
+
+char *argv0;
+
#define LENGTH(x) (sizeof x / sizeof x[0])
#define COOKIEJAR_TYPE (cookiejar_get_type ())
#define COOKIEJAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), COOKIEJAR_TYPE, CookieJar))
static GdkNativeWindow embed = 0;
static gboolean showxid = FALSE;
static char winid[64];
-static char *progname;
-static gboolean loadimage = 1, plugin = 1, script = 1;
+static gboolean loadimage = 1, plugin = 1, script = 1, using_proxy = 0;
+static char togglestat[6];
+static gboolean insertmode = FALSE;
static char *buildpath(const char *path);
static gboolean buttonrelease(WebKitWebView *web, GdkEventButton *e, GList *gl);
static const char *getatom(Client *c, int a);
static char *geturi(Client *c);
static gboolean initdownload(WebKitWebView *v, WebKitDownload *o, Client *c);
+static void insert(Client *c, const Arg *arg);
static gboolean keypress(GtkWidget *w, GdkEventKey *ev, Client *c);
static void linkhover(WebKitWebView *v, const char* t, const char* l, Client *c);
static void loadstatuschange(WebKitWebView *view, GParamSpec *pspec, Client *c);
static void eval(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 toggle(Client *c, const Arg *arg);
+static void gettogglestat(Client *c);
static void update(Client *c);
static void updatewinid(Client *c);
static void usage(void);
FILE *f;
/* creating directory */
- if(path[0] == '/')
+ if(path[0] == '/') {
apath = g_strdup(path);
- else
- apath = g_strconcat(g_get_home_dir(), "/", path, NULL);
+ } else if(path[0] == '~') {
+ if(path[1] == '/') {
+ apath = g_strconcat(g_get_home_dir(), &path[1], NULL);
+ } else {
+ apath = g_strconcat(g_get_home_dir(), "/",
+ &path[1], NULL);
+ }
+ } else {
+ apath = g_strconcat(g_get_current_dir(), "/", path, NULL);
+ }
+
if((p = strrchr(apath, '/'))) {
*p = '\0';
g_mkdir_with_parents(apath, 0700);
g_chmod(apath, 0600); /* always */
fclose(f);
}
+
return apath;
}
return g_object_new(COOKIEJAR_TYPE,
SOUP_COOKIE_JAR_TEXT_FILENAME, filename,
SOUP_COOKIE_JAR_READ_ONLY, read_only, NULL);
-}
+}
static void
cookiejar_set_property(GObject *self, guint prop_id, const GValue *value, GParamSpec *pspec) {
drawindicator(Client *c) {
gint width;
const char *uri;
+ char *colorname;
GtkWidget *w;
GdkGC *gc;
GdkColor fg;
w = c->indicator;
width = c->progress * w->allocation.width / 100;
gc = gdk_gc_new(w->window);
- if(strstr(uri, "https://") == uri)
- gdk_color_parse(c->sslfailed ?
- progress_untrust : progress_trust, &fg);
- else
- gdk_color_parse(progress, &fg);
+ if(strstr(uri, "https://") == uri) {
+ if(using_proxy) {
+ colorname = c->sslfailed? progress_proxy_untrust : progress_proxy_trust;
+ } else {
+ colorname = c->sslfailed? progress_untrust : progress_trust;
+ }
+ } else {
+ if(using_proxy) {
+ colorname = progress_proxy;
+ } else {
+ colorname = progress;
+ }
+ }
+
+ gdk_color_parse(colorname, &fg);
gdk_gc_set_rgb_fg_color(gc, &fg);
gdk_draw_rectangle(w->window,
w->style->bg_gc[GTK_WIDGET_STATE(w)],
return FALSE;
}
+void
+insert(Client *c, const Arg *arg) {
+ insertmode = TRUE;
+ update(clients);
+}
+
gboolean
keypress(GtkWidget* w, GdkEventKey *ev, Client *c) {
- guint i;
+ guint i, state;
gboolean processed = FALSE;
+ /* turn off insert mode */
+ if(insertmode && (ev->keyval == GDK_Escape)) {
+ insertmode = FALSE;
+ update(c);
+ return TRUE;
+ }
+
+ if(insertmode && (((ev->state & MODKEY) != MODKEY) || !MODKEY)) {
+ return FALSE;
+ }
+
+ if(ev->keyval == GDK_Escape) {
+ webkit_web_view_set_highlight_text_matches(c->view, FALSE);
+ return TRUE;
+ }
+
updatewinid(c);
for(i = 0; i < LENGTH(keys); i++) {
+ if(!insertmode && (MODKEY & keys[i].mod)) {
+ state = ev->state | MODKEY;
+ } else {
+ state = ev->state;
+ }
+
if(gdk_keyval_to_lower(ev->keyval) == keys[i].keyval
- && (ev->state & keys[i].mod) == keys[i].mod
&& keys[i].func) {
- keys[i].func(c, &(keys[i].arg));
- processed = TRUE;
+ if(state == keys[i].mod) {
+ keys[i].func(c, &(keys[i].arg));
+ processed = TRUE;
+ }
}
}
+
return processed;
}
linkhover(WebKitWebView *v, const char* t, const char* l, Client *c) {
if(l) {
c->linkhover = copystr(&c->linkhover, l);
- }
- else if(c->linkhover) {
+ } else if(c->linkhover) {
free(c->linkhover);
c->linkhover = NULL;
}
/* prevents endless loop */
if(c->uri && strcmp(u, c->uri) == 0) {
reload(c, &a);
- }
- else {
+ } else {
webkit_web_view_load_uri(c->view, u);
c->progress = 0;
c->title = copystr(&c->title, u);
/* Indicator */
c->indicator = gtk_drawing_area_new();
- gtk_widget_set_size_request(c->indicator, 0, 2);
+ gtk_widget_set_size_request(c->indicator, 0, indicator_thickness);
g_signal_connect (G_OBJECT (c->indicator), "expose_event",
G_CALLBACK (exposeindicator), c);
gtk_box_set_child_packing(GTK_BOX(c->vbox), c->scroll, TRUE, TRUE, 0, GTK_PACK_START);
gtk_widget_grab_focus(GTK_WIDGET(c->view));
gtk_widget_show(c->vbox);
- gtk_widget_show(c->indicator);
gtk_widget_show(c->scroll);
gtk_widget_show(GTK_WIDGET(c->view));
gtk_widget_show(c->win);
const Arg a = { .v = (void *)cmd };
char tmp[64];
- cmd[i++] = progname;
+ cmd[i++] = argv0;
if(embed && !noembed) {
cmd[i++] = "-e";
snprintf(tmp, LENGTH(tmp), "%u\n", (int)embed);
g_object_set(G_OBJECT(s), "proxy-uri", puri, NULL);
soup_uri_free(puri);
g_free(new_proxy);
+ using_proxy = 1;
}
}
update(c);
}
+void
+toggle(Client *c, const Arg *arg) {
+ WebKitWebSettings *settings;
+ char *name = (char *)arg->v;
+ gboolean value;
+ Arg a = { .b = FALSE };
+
+ settings = webkit_web_view_get_settings(c->view);
+ g_object_get(G_OBJECT(settings), name, &value, NULL);
+ g_object_set(G_OBJECT(settings), name, !value, NULL);
+
+ reload(c,&a);
+}
+
+void
+gettogglestat(Client *c){
+ gboolean value;
+ WebKitWebSettings *settings = webkit_web_view_get_settings(c->view);
+
+ togglestat[4] = '\0';
+ g_object_get(G_OBJECT(settings), "auto-load-images", &value, NULL);
+ togglestat[0] = value?'I':'i';
+ g_object_get(G_OBJECT(settings), "enable-scripts", &value, NULL);
+ togglestat[1] = value?'S':'s';
+ g_object_get(G_OBJECT(settings), "enable-plugins", &value, NULL);
+ togglestat[2] = value?'V':'v';
+ g_object_get(G_OBJECT(settings), "enable-caret-browsing",
+ &value, NULL);
+ togglestat[3] = value?'C':'c';
+
+ togglestat[4] = insertmode? '+' : '-';
+ togglestat[5] = '\0';
+}
+
+
void
update(Client *c) {
char *t;
- if(c->linkhover)
- t = g_strdup(c->linkhover);
- else if(c->progress != 100)
- t = g_strdup_printf("[%i%%] %s", c->progress, c->title);
- else
- t = g_strdup(c->title);
- drawindicator(c);
+ gettogglestat(c);
+
+ if(c->linkhover) {
+ t = g_strdup_printf("%s| %s", togglestat, c->linkhover);
+ } else if(c->progress != 100) {
+ drawindicator(c);
+ gtk_widget_show(c->indicator);
+ t = g_strdup_printf("[%i%%] %s| %s", c->progress, togglestat,
+ c->title);
+ } else {
+ gtk_widget_hide_all(c->indicator);
+ t = g_strdup_printf("%s| %s", togglestat, c->title);
+ }
+
gtk_window_set_title(GTK_WINDOW(c->win), t);
g_free(t);
}
void
usage(void) {
fputs("surf - simple browser\n", stderr);
- die("usage: surf [-e xid] [-i] [-p] [-s] [-v] [-x] [uri]\n");
+ die("usage: surf [-c cookiefile] [-e xid] [-i] [-p] [-r scriptfile]"
+ " [-s] [-t stylefile] [-u useragent] [-v] [-x] [uri]\n");
}
void
int
main(int argc, char *argv[]) {
- int i;
Arg arg;
- progname = argv[0];
+ memset(&arg, 0, sizeof(arg));
+
/* command line args */
- 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 = strtol(argv[i], NULL, 0);
- else
- usage();
- break;
- 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-2012 surf engineers, see LICENSE for details\n");
- default:
- usage();
- }
- }
- if(i < argc)
- arg.v = argv[i];
+ ARGBEGIN {
+ case 'c':
+ cookiefile = EARGF(usage());
+ break;
+ case 'e':
+ embed = strtol(EARGF(usage()), NULL, 0);
+ break;
+ case 'i':
+ loadimage = 0;
+ break;
+ case 'p':
+ plugin = 0;
+ break;
+ case 'r':
+ scriptfile = EARGF(usage());
+ break;
+ case 's':
+ script = 0;
+ break;
+ case 't':
+ stylefile = EARGF(usage());
+ break;
+ case 'u':
+ useragent = EARGF(usage());
+ break;
+ case 'x':
+ showxid = TRUE;
+ break;
+ case 'v':
+ die("surf-"VERSION", ©2009-2012 surf engineers, see LICENSE for details\n");
+ default:
+ usage();
+ } ARGEND;
+ if(argc > 0)
+ arg.v = argv[0];
+
setup();
newclient();
if(arg.v)
loaduri(clients, &arg);
+
gtk_main();
cleanup();
+
return EXIT_SUCCESS;
}
+