1 /* -*- c-basic-offset: 4; -*- */
2 // Original code taken from the example webkit-gtk+ application. see notice below.
3 // Modified code is licensed under the GPL 3. See LICENSE file.
7 * Copyright (C) 2006, 2007 Apple Inc.
8 * Copyright (C) 2007 Alp Toker <alp@atoker.com>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
26 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
27 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 #define LENGTH(x) (sizeof x / sizeof x[0])
34 #define MAX_BINDINGS 256
38 #include <gdk/gdkkeysyms.h>
39 #include <sys/socket.h>
41 #include <sys/types.h>
43 #include <sys/utsname.h>
44 #include <webkit/webkit.h>
52 #include <sys/socket.h>
54 #include <libsoup/soup.h>
61 /* define names and pointers to all config specific variables */
65 } var_name_to_ptr
[] = {
66 { "status_format", (void *)&uzbl
.behave
.status_format
},
67 { "show_status", (void *)&uzbl
.behave
.show_status
},
68 { "insert_mode", (void *)&uzbl
.behave
.insert_mode
},
70 }, *n2v_p
= var_name_to_ptr
;
72 /* construct a hash from the var_name_to_ptr array for quick access */
74 make_var_to_name_hash() {
75 uzbl
.comm
.proto_var
= g_hash_table_new(g_str_hash
, g_str_equal
);
77 g_hash_table_insert(uzbl
.comm
.proto_var
, n2v_p
->name
, n2v_p
->ptr
);
82 /* commandline arguments (set initial values for the state variables) */
83 static GOptionEntry entries
[] =
85 { "uri", 'u', 0, G_OPTION_ARG_STRING
, &uzbl
.state
.uri
, "Uri to load", "URI" },
86 { "name", 'n', 0, G_OPTION_ARG_STRING
, &uzbl
.state
.instance_name
, "Name of the current instance", "NAME" },
87 { "config", 'c', 0, G_OPTION_ARG_STRING
, &uzbl
.state
.config_file
, "Config file", "FILE" },
88 { NULL
, 0, 0, 0, NULL
, NULL
, NULL
}
91 typedef void (*Command
)(WebKitWebView
*, const char *);
94 static char *XDG_CONFIG_HOME_default
[256];
95 static char *XDG_CONFIG_DIRS_default
= "/etc/xdg";
98 /* --- UTILITY FUNCTIONS --- */
104 snprintf(tmp
, sizeof(tmp
), "%i", val
);
105 return g_strdup(tmp
);
109 str_replace (const char* search
, const char* replace
, const char* string
) {
110 return g_strjoinv (replace
, g_strsplit(string
, search
, -1));
114 setup_signal(int signr
, sigfunc
*shandler
) {
115 struct sigaction nh
, oh
;
117 nh
.sa_handler
= shandler
;
118 sigemptyset(&nh
.sa_mask
);
121 if(sigaction(signr
, &nh
, &oh
) < 0)
129 if (uzbl
.behave
.fifo_dir
)
130 unlink (uzbl
.comm
.fifo_path
);
131 if (uzbl
.behave
.socket_dir
)
132 unlink (uzbl
.comm
.socket_path
);
134 g_string_free(uzbl
.state
.keycmd
, TRUE
);
135 g_hash_table_destroy(uzbl
.bindings
);
136 g_hash_table_destroy(uzbl
.behave
.commands
);
140 /* --- SIGNAL HANDLER --- */
143 catch_sigterm(int s
) {
148 /* --- CALLBACKS --- */
151 new_window_cb (WebKitWebView
*web_view
, WebKitWebFrame
*frame
, WebKitNetworkRequest
*request
, WebKitWebNavigationAction
*navigation_action
, WebKitWebPolicyDecision
*policy_decision
, gpointer user_data
) {
154 (void) navigation_action
;
155 (void) policy_decision
;
157 const gchar
* uri
= webkit_network_request_get_uri (request
);
158 printf("New window requested -> %s \n", uri
);
159 new_window_load_uri(uri
);
164 create_web_view_cb (WebKitWebView
*web_view
, WebKitWebFrame
*frame
, gpointer user_data
) {
168 if (uzbl
.state
.selected_url
[0]!=0) {
169 printf("\nNew web view -> %s\n",uzbl
.state
.selected_url
);
170 new_window_load_uri(uzbl
.state
.selected_url
);
172 printf("New web view -> %s\n","Nothing to open, exiting");
178 download_cb (WebKitWebView
*web_view
, GObject
*download
, gpointer user_data
) {
181 if (uzbl
.behave
.download_handler
) {
182 const gchar
* uri
= webkit_download_get_uri ((WebKitDownload
*)download
);
183 printf("Download -> %s\n",uri
);
184 run_command_async(uzbl
.behave
.download_handler
, uri
);
189 /* scroll a bar in a given direction */
191 scroll (GtkAdjustment
* bar
, const char *param
) {
195 amount
= g_ascii_strtod(param
, &end
);
198 fprintf(stderr
, "found something after double: %s\n", end
);
200 gtk_adjustment_set_value (bar
, gtk_adjustment_get_value(bar
)+amount
);
203 static void scroll_vert(WebKitWebView
* page
, const char *param
) {
206 scroll(uzbl
.gui
.bar_v
, param
);
209 static void scroll_horz(WebKitWebView
* page
, const char *param
) {
212 scroll(uzbl
.gui
.bar_h
, param
);
217 if (!uzbl
.behave
.show_status
) {
218 gtk_widget_hide(uzbl
.gui
.mainbar
);
220 gtk_widget_show(uzbl
.gui
.mainbar
);
226 toggle_status_cb (WebKitWebView
* page
, const char *param
) {
230 if (uzbl
.behave
.show_status
) {
231 gtk_widget_hide(uzbl
.gui
.mainbar
);
233 gtk_widget_show(uzbl
.gui
.mainbar
);
235 uzbl
.behave
.show_status
= !uzbl
.behave
.show_status
;
240 link_hover_cb (WebKitWebView
* page
, const gchar
* title
, const gchar
* link
, gpointer data
) {
244 //ADD HOVER URL TO WINDOW TITLE
245 uzbl
.state
.selected_url
[0] = '\0';
247 strcpy (uzbl
.state
.selected_url
, link
);
253 title_change_cb (WebKitWebView
* web_view
, WebKitWebFrame
* web_frame
, const gchar
* title
, gpointer data
) {
257 if (uzbl
.gui
.main_title
)
258 g_free (uzbl
.gui
.main_title
);
259 uzbl
.gui
.main_title
= g_strdup (title
);
264 progress_change_cb (WebKitWebView
* page
, gint progress
, gpointer data
) {
267 uzbl
.gui
.sbar
.load_progress
= progress
;
272 load_commit_cb (WebKitWebView
* page
, WebKitWebFrame
* frame
, gpointer data
) {
275 free (uzbl
.state
.uri
);
276 GString
* newuri
= g_string_new (webkit_web_frame_get_uri (frame
));
277 uzbl
.state
.uri
= g_string_free (newuri
, FALSE
);
281 destroy_cb (GtkWidget
* widget
, gpointer data
) {
289 if (uzbl
.behave
.history_handler
) {
291 struct tm
* timeinfo
;
294 timeinfo
= localtime ( &rawtime
);
295 strftime (date
, 80, "%Y-%m-%d %H:%M:%S", timeinfo
);
296 GString
* args
= g_string_new ("");
297 g_string_printf (args
, "'%s'", date
);
298 run_command_async(uzbl
.behave
.history_handler
, args
->str
);
299 g_string_free (args
, TRUE
);
304 /* VIEW funcs (little webkit wrappers) */
305 #define VIEWFUNC(name) static void view_##name(WebKitWebView *page, const char *param){(void)param; webkit_web_view_##name(page);}
307 VIEWFUNC(reload_bypass_cache
)
308 VIEWFUNC(stop_loading
)
315 /* -- command to callback/function map for things we cannot attach to any signals */
318 static struct {char *name
; Command command
;} cmdlist
[] =
320 { "back", view_go_back
},
321 { "forward", view_go_forward
},
322 { "scroll_vert", scroll_vert
},
323 { "scroll_horz", scroll_horz
},
324 { "reload", view_reload
, },
325 { "reload_ign_cache", view_reload_bypass_cache
},
326 { "stop", view_stop_loading
, },
327 { "zoom_in", view_zoom_in
, }, //Can crash (when max zoom reached?).
328 { "zoom_out", view_zoom_out
, },
330 { "script", run_js
},
331 { "toggle_status", toggle_status_cb
},
333 { "exit", close_uzbl
},
334 { "search", search_text
},
335 { "insert_mode", set_insert_mode
}
342 uzbl
.behave
.commands
= g_hash_table_new(g_str_hash
, g_str_equal
);
344 for (i
= 0; i
< LENGTH(cmdlist
); i
++)
345 g_hash_table_insert(uzbl
.behave
.commands
, cmdlist
[i
].name
, cmdlist
[i
].command
);
348 /* -- CORE FUNCTIONS -- */
351 free_action(gpointer act
) {
352 Action
*action
= (Action
*)act
;
353 g_free(action
->name
);
355 g_free(action
->param
);
360 new_action(const gchar
*name
, const gchar
*param
) {
361 Action
*action
= g_new(Action
, 1);
363 action
->name
= g_strdup(name
);
365 action
->param
= g_strdup(param
);
367 action
->param
= NULL
;
373 file_exists (const char * filename
) {
374 FILE *file
= fopen (filename
, "r");
383 set_insert_mode(WebKitWebView
*page
, const gchar
*param
) {
387 uzbl
.behave
.insert_mode
= TRUE
;
392 load_uri (WebKitWebView
* web_view
, const gchar
*param
) {
394 GString
* newuri
= g_string_new (param
);
395 if (g_strrstr (param
, "://") == NULL
)
396 g_string_prepend (newuri
, "http://");
397 /* if we do handle cookies, ask our handler for them */
398 webkit_web_view_load_uri (web_view
, newuri
->str
);
399 g_string_free (newuri
, TRUE
);
404 run_js (WebKitWebView
* web_view
, const gchar
*param
) {
406 webkit_web_view_execute_script (web_view
, param
);
410 search_text (WebKitWebView
*page
, const char *param
) {
411 if ((param
) && (param
[0] != '\0')) {
412 strcpy(uzbl
.state
.searchtx
, param
);
414 if (uzbl
.state
.searchtx
[0] != '\0') {
415 printf ("Searching: %s\n", uzbl
.state
.searchtx
);
416 webkit_web_view_unmark_text_matches (page
);
417 webkit_web_view_mark_text_matches (page
, uzbl
.state
.searchtx
, FALSE
, 0);
418 webkit_web_view_set_highlight_text_matches (page
, TRUE
);
419 webkit_web_view_search_text (page
, uzbl
.state
.searchtx
, FALSE
, TRUE
, TRUE
);
424 new_window_load_uri (const gchar
* uri
) {
425 GString
* to_execute
= g_string_new ("");
426 g_string_append_printf (to_execute
, "%s --uri '%s'", uzbl
.state
.executable_path
, uri
);
428 for (i
= 0; entries
[i
].long_name
!= NULL
; i
++) {
429 if ((entries
[i
].arg
== G_OPTION_ARG_STRING
) && (strcmp(entries
[i
].long_name
,"uri")!=0)) {
430 gchar
** str
= (gchar
**)entries
[i
].arg_data
;
432 g_string_append_printf (to_execute
, " --%s '%s'", entries
[i
].long_name
, *str
);
436 printf("\n%s\n", to_execute
->str
);
437 g_spawn_command_line_async (to_execute
->str
, NULL
);
438 g_string_free (to_execute
, TRUE
);
442 close_uzbl (WebKitWebView
*page
, const char *param
) {
448 /* --Statusbar functions-- */
450 build_progressbar_ascii(int percent
) {
454 GString
*bar
= g_string_new("");
456 l
= (double)percent
*((double)width
/100.);
457 l
= (int)(l
+.5)>=(int)l
? l
+.5 : l
;
459 g_string_append(bar
, "[");
460 for(i
=0; i
<(int)l
; i
++)
461 g_string_append(bar
, "=");
464 g_string_append(bar
, "·");
465 g_string_append(bar
, "]");
467 return g_string_free(bar
, FALSE
);
472 const GScannerConfig scan_config
= {
475 ) /* cset_skip_characters */,
480 ) /* cset_identifier_first */,
487 ) /* cset_identifier_nth */,
488 ( "" ) /* cpair_comment_single */,
490 TRUE
/* case_sensitive */,
492 FALSE
/* skip_comment_multi */,
493 FALSE
/* skip_comment_single */,
494 FALSE
/* scan_comment_multi */,
495 TRUE
/* scan_identifier */,
496 TRUE
/* scan_identifier_1char */,
497 FALSE
/* scan_identifier_NULL */,
498 TRUE
/* scan_symbols */,
499 FALSE
/* scan_binary */,
500 FALSE
/* scan_octal */,
501 FALSE
/* scan_float */,
502 FALSE
/* scan_hex */,
503 FALSE
/* scan_hex_dollar */,
504 FALSE
/* scan_string_sq */,
505 FALSE
/* scan_string_dq */,
506 TRUE
/* numbers_2_int */,
507 FALSE
/* int_2_float */,
508 FALSE
/* identifier_2_string */,
509 FALSE
/* char_2_token */,
510 FALSE
/* symbol_2_token */,
511 TRUE
/* scope_0_fallback */,
516 uzbl
.scan
= g_scanner_new(&scan_config
);
517 while(symp
->symbol_name
) {
518 g_scanner_scope_add_symbol(uzbl
.scan
, 0,
520 GINT_TO_POINTER(symp
->symbol_token
));
526 parse_status_template(const char *template) {
527 GTokenType token
= G_TOKEN_NONE
;
528 GString
*ret
= g_string_new("");
535 g_scanner_input_text(uzbl
.scan
, template, strlen(template));
536 while(!g_scanner_eof(uzbl
.scan
) && token
!= G_TOKEN_LAST
) {
537 token
= g_scanner_get_next_token(uzbl
.scan
);
539 if(token
== G_TOKEN_SYMBOL
) {
540 sym
= (int)g_scanner_cur_value(uzbl
.scan
).v_symbol
;
545 g_markup_printf_escaped("%s", uzbl
.state
.uri
):"");
548 g_string_append(ret
, itos(uzbl
.gui
.sbar
.load_progress
));
550 case SYM_LOADPRGSBAR
:
551 buf
= build_progressbar_ascii(uzbl
.gui
.sbar
.load_progress
);
552 g_string_append(ret
, buf
);
558 g_markup_printf_escaped("%s", uzbl
.gui
.main_title
):"");
562 uzbl
.state
.instance_name
?uzbl
.state
.instance_name
:itos(uzbl
.xwin
));
566 uzbl
.state
.keycmd
->str
?
567 g_markup_printf_escaped("%s", uzbl
.state
.keycmd
->str
):"");
571 uzbl
.behave
.insert_mode
?"[I]":"[C]");
577 else if(token
== G_TOKEN_INT
) {
578 g_string_append(ret
, itos(g_scanner_cur_value(uzbl
.scan
).v_int
));
580 else if(token
== G_TOKEN_IDENTIFIER
) {
581 g_string_append(ret
, (gchar
*)g_scanner_cur_value(uzbl
.scan
).v_identifier
);
583 else if(token
== G_TOKEN_CHAR
) {
584 g_string_append_c(ret
, (gchar
)g_scanner_cur_value(uzbl
.scan
).v_char
);
588 return g_string_free(ret
, FALSE
);
590 /* --End Statusbar functions-- */
593 // make sure to put '' around args, so that if there is whitespace we can still keep arguments together.
595 run_command_async(const char *command
, const char *args
) {
596 //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
597 GString
* to_execute
= g_string_new ("");
599 g_string_printf (to_execute
, "%s '%s' '%i' '%i' '%s' '%s'",
600 command
, uzbl
.state
.config_file
, (int) getpid() ,
601 (int) uzbl
.xwin
, uzbl
.comm
.fifo_path
, uzbl
.comm
.socket_path
);
602 g_string_append_printf (to_execute
, " '%s' '%s'",
603 uzbl
.state
.uri
, "TODO title here");
605 g_string_append_printf (to_execute
, " %s", args
);
607 result
= g_spawn_command_line_async (to_execute
->str
, NULL
);
608 printf("Called %s. Result: %s\n", to_execute
->str
, (result
? "TRUE" : "FALSE" ));
609 g_string_free (to_execute
, TRUE
);
614 run_command_sync(const char *command
, const char *args
, char **stdout
) {
615 //command <uzbl conf> <uzbl pid> <uzbl win id> <uzbl fifo file> <uzbl socket file> [args]
616 GString
* to_execute
= g_string_new ("");
618 g_string_printf (to_execute
, "%s '%s' '%i' '%i' '%s' '%s'", command
, uzbl
.state
.config_file
, (int) getpid() , (int) uzbl
.xwin
, uzbl
.comm
.fifo_path
, uzbl
.comm
.socket_path
);
619 g_string_append_printf (to_execute
, " '%s' '%s'", uzbl
.state
.uri
, "TODO title here");
621 g_string_append_printf (to_execute
, " %s", args
);
623 result
= g_spawn_command_line_sync (to_execute
->str
, stdout
, NULL
, NULL
, NULL
);
624 printf("Called %s. Result: %s\n", to_execute
->str
, (result
? "TRUE" : "FALSE" ));
625 g_string_free (to_execute
, TRUE
);
630 spawn(WebKitWebView
*web_view
, const char *param
) {
632 run_command_async(param
, NULL
);
636 parse_command(const char *cmd
, const char *param
) {
639 if ((c
= g_hash_table_lookup(uzbl
.behave
.commands
, cmd
)))
640 c(uzbl
.gui
.web_view
, param
);
642 fprintf (stderr
, "command \"%s\" not understood. ignoring.\n", cmd
);
646 parse_line(char *line
) {
651 parts
= g_strsplit(line
, " ", 2);
656 parse_command(parts
[0], parts
[1]);
662 build_stream_name(int type
) {
664 State
*s
= &uzbl
.state
;
665 Behaviour
*b
= &uzbl
.behave
;
667 xwin_str
= itos((int)uzbl
.xwin
);
671 sprintf (uzbl
.comm
.fifo_path
, "%s/uzbl_fifo_%s",
673 s
->instance_name
? s
->instance_name
: xwin_str
);
675 sprintf (uzbl
.comm
.fifo_path
, "/tmp/uzbl_fifo_%s",
676 s
->instance_name
? s
->instance_name
: xwin_str
);
682 sprintf (uzbl
.comm
.socket_path
, "%s/uzbl_socket_%s",
684 s
->instance_name
? s
->instance_name
: xwin_str
);
686 sprintf (uzbl
.comm
.socket_path
, "/tmp/uzbl_socket_%s",
687 s
->instance_name
? s
->instance_name
: xwin_str
);
697 control_fifo(GIOChannel
*gio
, GIOCondition condition
) {
698 printf("triggered\n");
703 if (condition
& G_IO_HUP
)
704 g_error ("Fifo: Read end of pipe died!\n");
707 g_error ("Fifo: GIOChannel broke\n");
709 ret
= g_io_channel_read_line(gio
, &ctl_line
, NULL
, NULL
, &err
);
710 if (ret
== G_IO_STATUS_ERROR
)
711 g_error ("Fifo: Error reading: %s\n", err
->message
);
713 parse_line(ctl_line
);
721 GIOChannel
*chan
= NULL
;
722 GError
*error
= NULL
;
724 build_stream_name(FIFO
);
725 if (file_exists(uzbl
.comm
.fifo_path
)) {
726 g_error ("Fifo: Error when creating %s: File exists\n", uzbl
.comm
.fifo_path
);
729 if (mkfifo (uzbl
.comm
.fifo_path
, 0666) == -1) {
730 g_error ("Fifo: Error when creating %s: %s\n", uzbl
.comm
.fifo_path
, strerror(errno
));
732 // we don't really need to write to the file, but if we open the file as 'r' we will block here, waiting for a writer to open the file.
733 chan
= g_io_channel_new_file((gchar
*) uzbl
.comm
.fifo_path
, "r+", &error
);
735 if (!g_io_add_watch(chan
, G_IO_IN
|G_IO_HUP
, (GIOFunc
) control_fifo
, NULL
)) {
736 g_error ("Fifo: could not add watch on %s\n", uzbl
.comm
.fifo_path
);
738 printf ("Fifo: created successfully as %s\n", uzbl
.comm
.fifo_path
);
741 g_error ("Fifo: Error while opening: %s\n", error
->message
);
748 get_var_value(gchar
*name
) {
751 if( (p
= g_hash_table_lookup(uzbl
.comm
.proto_var
, name
)) ) {
752 if(!strcmp(name
, "name")) {
753 printf("VAR: %s VALUE: %s\n", name
, (char *)*p
);
755 printf("VAR: %s VALUE: %d\n", name
, (int)*p
);
762 set_var_value(gchar
*name
, gchar
*val
) {
766 if( (p
= g_hash_table_lookup(uzbl
.comm
.proto_var
, name
)) ) {
767 if(!strcmp(name
, "status_format")) {
772 /* variables that take int values */
774 *p
= (int)strtoul(val
, &endp
, 10);
776 if(!strcmp(name
, "show_status")) {
788 uzbl
.comm
.get_regex
= g_regex_new("^GET\\s+([^ \\n]+)$", 0, 0, &err
);
789 uzbl
.comm
.set_regex
= g_regex_new("^SET\\s+([^ ]+)\\s*=\\s*([^\\n].*)$", 0, 0, &err
);
790 uzbl
.comm
.bind_regex
= g_regex_new("^BIND\\s+(.*[^ ])\\s*=\\s*([a-z][^\\n].+)$", 0, 0, &err
);
794 control_stdin(GIOChannel
*gio
, GIOCondition condition
) {
795 gchar
*ctl_line
= NULL
;
796 gsize ctl_line_len
= 0;
801 if (condition
& G_IO_HUP
) {
802 ret
= g_io_channel_shutdown (gio
, FALSE
, &err
);
806 ret
= g_io_channel_read_line(gio
, &ctl_line
, &ctl_line_len
, NULL
, &err
);
807 if ( (ret
== G_IO_STATUS_ERROR
) || (ret
== G_IO_STATUS_EOF
) )
811 if(ctl_line
[0] == 'S') {
812 tokens
= g_regex_split(uzbl
.comm
.set_regex
, ctl_line
, 0);
813 if(tokens
[0][0] == 0) {
814 set_var_value(tokens
[1], tokens
[2]);
818 printf("Error in command: %s\n", tokens
[0]);
821 else if(ctl_line
[0] == 'G') {
822 tokens
= g_regex_split(uzbl
.comm
.get_regex
, ctl_line
, 0);
823 if(tokens
[0][0] == 0) {
824 get_var_value(tokens
[1]);
828 printf("Error in command: %s\n", tokens
[0]);
831 else if(ctl_line
[0] == 'B') {
832 tokens
= g_regex_split(uzbl
.comm
.bind_regex
, ctl_line
, 0);
833 if(tokens
[0][0] == 0) {
834 add_binding(tokens
[1], tokens
[2]);
838 printf("Error in command: %s\n", tokens
[0]);
841 printf("Command not understood (%s)\n", ctl_line
);
850 GIOChannel
*chan
= NULL
;
851 GError
*error
= NULL
;
853 chan
= g_io_channel_unix_new(fileno(stdin
));
855 if (!g_io_add_watch(chan
, G_IO_IN
|G_IO_HUP
, (GIOFunc
) control_stdin
, NULL
)) {
856 g_error ("Stdin: could not add watch\n");
858 printf ("Stdin: watch added successfully\n");
861 g_error ("Stdin: Error while opening: %s\n", error
->message
);
866 control_socket(GIOChannel
*chan
) {
867 struct sockaddr_un remote
;
868 char buffer
[512], *ctl_line
;
870 int sock
, clientsock
, n
, done
;
873 sock
= g_io_channel_unix_get_fd(chan
);
875 memset (buffer
, 0, sizeof (buffer
));
878 clientsock
= accept (sock
, (struct sockaddr
*) &remote
, &t
);
882 memset (temp
, 0, sizeof (temp
));
883 n
= recv (clientsock
, temp
, 128, 0);
885 buffer
[strlen (buffer
)] = '\0';
889 strcat (buffer
, temp
);
892 if (strcmp (buffer
, "\n") < 0) {
893 buffer
[strlen (buffer
) - 1] = '\0';
895 buffer
[strlen (buffer
)] = '\0';
898 ctl_line
= g_strdup(buffer
);
899 parse_line (ctl_line
);
902 TODO: we should be able to do it with this. but glib errors out with "Invalid argument"
903 GError *error = NULL;
906 ret = g_io_channel_read_line(chan, &ctl_line, &len, NULL, &error);
907 if (ret == G_IO_STATUS_ERROR)
908 g_error ("Error reading: %s\n", error->message);
910 printf("Got line %s (%u bytes) \n",ctl_line, len);
912 parse_line(ctl_line);
921 GIOChannel
*chan
= NULL
;
923 struct sockaddr_un local
;
925 build_stream_name(SOCKET
);
926 sock
= socket (AF_UNIX
, SOCK_STREAM
, 0);
928 local
.sun_family
= AF_UNIX
;
929 strcpy (local
.sun_path
, uzbl
.comm
.socket_path
);
930 unlink (local
.sun_path
);
932 len
= strlen (local
.sun_path
) + sizeof (local
.sun_family
);
933 bind (sock
, (struct sockaddr
*) &local
, len
);
936 printf ("Socket: Could not open in %s: %s\n", uzbl
.comm
.socket_path
, strerror(errno
));
938 printf ("Socket: Opened in %s\n", uzbl
.comm
.socket_path
);
941 if( (chan
= g_io_channel_unix_new(sock
)) )
942 g_io_add_watch(chan
, G_IO_IN
|G_IO_HUP
, (GIOFunc
) control_socket
, chan
);
947 update_title (void) {
948 GString
* string_long
= g_string_new ("");
949 GString
* string_short
= g_string_new ("");
953 State
*s
= &uzbl
.state
;
954 Behaviour
*b
= &uzbl
.behave
;
956 if(s
->instance_name
) {
957 iname_len
= strlen(s
->instance_name
)+4;
958 iname
= malloc(iname_len
);
959 snprintf(iname
, iname_len
, "<%s> ", s
->instance_name
);
961 g_string_prepend(string_long
, iname
);
962 g_string_prepend(string_short
, iname
);
966 g_string_append_printf(string_long
, "%s ", s
->keycmd
->str
);
967 if (!b
->always_insert_mode
)
968 g_string_append (string_long
, (b
->insert_mode
? "[I] " : "[C] "));
969 if (uzbl
.gui
.main_title
) {
970 g_string_append (string_long
, uzbl
.gui
.main_title
);
971 g_string_append (string_short
, uzbl
.gui
.main_title
);
973 g_string_append (string_long
, " - Uzbl browser");
974 g_string_append (string_short
, " - Uzbl browser");
975 if (s
->selected_url
[0]!=0) {
976 g_string_append_printf (string_long
, " -> (%s)", s
->selected_url
);
979 gchar
* title_long
= g_string_free (string_long
, FALSE
);
980 gchar
* title_short
= g_string_free (string_short
, FALSE
);
982 if (b
->show_status
) {
983 gtk_window_set_title (GTK_WINDOW(uzbl
.gui
.main_window
), title_short
);
984 // TODO: we should probably not do this every time we want to update the title..?
985 statln
= parse_status_template(uzbl
.behave
.status_format
);
986 gtk_label_set_markup(GTK_LABEL(uzbl
.gui
.mainbar_label
), statln
);
987 if (b
->status_background
) {
989 gdk_color_parse (b
->status_background
, &color
);
990 //labels and hboxes do not draw their own background. applying this on the window is ok as we the statusbar is the only affected widget. (if not, we could also use GtkEventBox)
991 gtk_widget_modify_bg (uzbl
.gui
.main_window
, GTK_STATE_NORMAL
, &color
);
995 gtk_window_set_title (GTK_WINDOW(uzbl
.gui
.main_window
), title_long
);
999 g_free (title_short
);
1003 key_press_cb (WebKitWebView
* page
, GdkEventKey
* event
)
1005 //TRUE to stop other handlers from being invoked for the event. FALSE to propagate the event further.
1010 if (event
->type
!= GDK_KEY_PRESS
|| event
->keyval
== GDK_Page_Up
|| event
->keyval
== GDK_Page_Down
1011 || event
->keyval
== GDK_Up
|| event
->keyval
== GDK_Down
|| event
->keyval
== GDK_Left
|| event
->keyval
== GDK_Right
)
1014 /* turn off insert mode (if always_insert_mode is not used) */
1015 if (uzbl
.behave
.insert_mode
&& (event
->keyval
== GDK_Escape
)) {
1016 uzbl
.behave
.insert_mode
= uzbl
.behave
.always_insert_mode
;
1021 if (uzbl
.behave
.insert_mode
&& ((event
->state
& uzbl
.behave
.modmask
) != uzbl
.behave
.modmask
))
1024 if (event
->keyval
== GDK_Escape
) {
1025 g_string_truncate(uzbl
.state
.keycmd
, 0);
1030 //Insert without shift - insert from clipboard; Insert with shift - insert from primary
1031 if (event
->keyval
== GDK_Insert
) {
1033 if ((event
->state
& GDK_SHIFT_MASK
) == GDK_SHIFT_MASK
) {
1034 str
= gtk_clipboard_wait_for_text (gtk_clipboard_get (GDK_SELECTION_PRIMARY
));
1036 str
= gtk_clipboard_wait_for_text (gtk_clipboard_get (GDK_SELECTION_CLIPBOARD
));
1039 g_string_append_printf (uzbl
.state
.keycmd
, "%s", str
);
1046 if ((event
->keyval
== GDK_BackSpace
) && (uzbl
.state
.keycmd
->len
> 0)) {
1047 g_string_truncate(uzbl
.state
.keycmd
, uzbl
.state
.keycmd
->len
- 1);
1052 if ((event
->keyval
== GDK_Return
) || (event
->keyval
== GDK_KP_Enter
)) {
1053 GString
* short_keys
= g_string_new ("");
1055 for (i
=0; i
<(uzbl
.state
.keycmd
->len
); i
++) {
1056 g_string_append_c(short_keys
, uzbl
.state
.keycmd
->str
[i
]);
1057 g_string_append_c(short_keys
, '_');
1059 //printf("\nTesting string: @%s@\n", short_keys->str);
1060 if ((action
= g_hash_table_lookup(uzbl
.bindings
, short_keys
->str
))) {
1061 GString
* parampart
= g_string_new (uzbl
.state
.keycmd
->str
);
1062 g_string_erase (parampart
, 0, i
+1);
1063 //printf("\nParameter: @%s@\n", parampart->str);
1064 GString
* actionname
= g_string_new ("");
1066 g_string_printf (actionname
, action
->name
, parampart
->str
);
1067 GString
* actionparam
= g_string_new ("");
1069 g_string_printf (actionparam
, action
->param
, parampart
->str
);
1070 parse_command(actionname
->str
, actionparam
->str
);
1071 g_string_free (actionname
, TRUE
);
1072 g_string_free (actionparam
, TRUE
);
1073 g_string_free (parampart
, TRUE
);
1074 g_string_truncate(uzbl
.state
.keycmd
, 0);
1078 g_string_truncate(short_keys
, short_keys
->len
- 1);
1080 g_string_free (short_keys
, TRUE
);
1081 return (!uzbl
.behave
.insert_mode
);
1084 g_string_append(uzbl
.state
.keycmd
, event
->string
);
1085 if ((action
= g_hash_table_lookup(uzbl
.bindings
, uzbl
.state
.keycmd
->str
))) {
1086 g_string_truncate(uzbl
.state
.keycmd
, 0);
1087 parse_command(action
->name
, action
->param
);
1099 GtkWidget
* scrolled_window
= gtk_scrolled_window_new (NULL
, NULL
);
1100 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window
), GTK_POLICY_NEVER
, GTK_POLICY_NEVER
); //todo: some sort of display of position/total length. like what emacs does
1102 g
->web_view
= WEBKIT_WEB_VIEW (webkit_web_view_new ());
1103 gtk_container_add (GTK_CONTAINER (scrolled_window
), GTK_WIDGET (g
->web_view
));
1105 g_signal_connect (G_OBJECT (g
->web_view
), "title-changed", G_CALLBACK (title_change_cb
), g
->web_view
);
1106 g_signal_connect (G_OBJECT (g
->web_view
), "load-progress-changed", G_CALLBACK (progress_change_cb
), g
->web_view
);
1107 g_signal_connect (G_OBJECT (g
->web_view
), "load-committed", G_CALLBACK (load_commit_cb
), g
->web_view
);
1108 g_signal_connect (G_OBJECT (g
->web_view
), "load-committed", G_CALLBACK (log_history_cb
), g
->web_view
);
1109 g_signal_connect (G_OBJECT (g
->web_view
), "hovering-over-link", G_CALLBACK (link_hover_cb
), g
->web_view
);
1110 g_signal_connect (G_OBJECT (g
->web_view
), "key-press-event", G_CALLBACK (key_press_cb
), g
->web_view
);
1111 g_signal_connect (G_OBJECT (g
->web_view
), "new-window-policy-decision-requested", G_CALLBACK (new_window_cb
), g
->web_view
);
1112 g_signal_connect (G_OBJECT (g
->web_view
), "download-requested", G_CALLBACK (download_cb
), g
->web_view
);
1113 g_signal_connect (G_OBJECT (g
->web_view
), "create-web-view", G_CALLBACK (create_web_view_cb
), g
->web_view
);
1115 return scrolled_window
;
1122 g
->mainbar
= gtk_hbox_new (FALSE
, 0);
1123 g
->mainbar_label
= gtk_label_new ("");
1124 gtk_label_set_selectable((GtkLabel
*)g
->mainbar_label
, TRUE
);
1125 gtk_label_set_ellipsize(GTK_LABEL(g
->mainbar_label
), PANGO_ELLIPSIZE_END
);
1126 gtk_misc_set_alignment (GTK_MISC(g
->mainbar_label
), 0, 0);
1127 gtk_misc_set_padding (GTK_MISC(g
->mainbar_label
), 2, 2);
1128 gtk_box_pack_start (GTK_BOX (g
->mainbar
), g
->mainbar_label
, TRUE
, TRUE
, 0);
1133 GtkWidget
* create_window () {
1134 GtkWidget
* window
= gtk_window_new (GTK_WINDOW_TOPLEVEL
);
1135 gtk_window_set_default_size (GTK_WINDOW (window
), 800, 600);
1136 gtk_widget_set_name (window
, "Uzbl browser");
1137 g_signal_connect (G_OBJECT (window
), "destroy", G_CALLBACK (destroy_cb
), NULL
);
1143 add_binding (const gchar
*key
, const gchar
*act
) {
1144 char **parts
= g_strsplit(act
, " ", 2);
1151 printf ("Binding %-10s : %s\n", key
, act
);
1152 action
= new_action(parts
[0], parts
[1]);
1153 g_hash_table_insert(uzbl
.bindings
, g_strdup(key
), action
);
1160 GKeyFile
* config
= NULL
;
1161 gboolean res
= FALSE
;
1163 gchar
** keys
= NULL
;
1164 State
*s
= &uzbl
.state
;
1165 Network
*n
= &uzbl
.net
;
1166 Behaviour
*b
= &uzbl
.behave
;
1168 if (!s
->config_file
) {
1169 const char* XDG_CONFIG_HOME
= getenv ("XDG_CONFIG_HOME");
1170 if (! XDG_CONFIG_HOME
|| ! strcmp (XDG_CONFIG_HOME
, "")) {
1171 XDG_CONFIG_HOME
= (char*)XDG_CONFIG_HOME_default
;
1173 printf("XDG_CONFIG_HOME: %s\n", XDG_CONFIG_HOME
);
1175 strcpy (s
->config_file_path
, XDG_CONFIG_HOME
);
1176 strcat (s
->config_file_path
, "/uzbl/config");
1177 if (file_exists (s
->config_file_path
)) {
1178 printf ("Config file %s found.\n", s
->config_file_path
);
1179 s
->config_file
= &s
->config_file_path
[0];
1181 // Now we check $XDG_CONFIG_DIRS
1182 char *XDG_CONFIG_DIRS
= getenv ("XDG_CONFIG_DIRS");
1183 if (! XDG_CONFIG_DIRS
|| ! strcmp (XDG_CONFIG_DIRS
, ""))
1184 XDG_CONFIG_DIRS
= XDG_CONFIG_DIRS_default
;
1186 printf("XDG_CONFIG_DIRS: %s\n", XDG_CONFIG_DIRS
);
1189 strcpy (buffer
, XDG_CONFIG_DIRS
);
1190 const gchar
* dir
= (char *) strtok_r (buffer
, ":", &saveptr
);
1191 while (dir
&& ! file_exists (s
->config_file_path
)) {
1192 strcpy (s
->config_file_path
, dir
);
1193 strcat (s
->config_file_path
, "/uzbl/config_file_pathig");
1194 if (file_exists (s
->config_file_path
)) {
1195 printf ("Config file %s found.\n", s
->config_file_path
);
1196 s
->config_file
= &s
->config_file_path
[0];
1198 dir
= (char * ) strtok_r (NULL
, ":", &saveptr
);
1203 if (s
->config_file
) {
1204 config
= g_key_file_new ();
1205 res
= g_key_file_load_from_file (config
, s
->config_file
, G_KEY_FILE_NONE
, NULL
);
1207 printf ("Config %s loaded\n", s
->config_file
);
1209 fprintf (stderr
, "Config %s loading failed\n", s
->config_file
);
1212 printf ("No configuration.\n");
1216 b
->history_handler
= g_key_file_get_value (config
, "behavior", "history_handler", NULL
);
1217 b
->download_handler
= g_key_file_get_value (config
, "behavior", "download_handler", NULL
);
1218 b
->cookie_handler
= g_key_file_get_string (config
, "behavior", "cookie_handler", NULL
);
1219 b
->always_insert_mode
= g_key_file_get_boolean (config
, "behavior", "always_insert_mode", NULL
);
1220 b
->show_status
= g_key_file_get_boolean (config
, "behavior", "show_status", NULL
);
1221 b
->modkey
= g_key_file_get_value (config
, "behavior", "modkey", NULL
);
1222 b
->status_top
= g_key_file_get_boolean (config
, "behavior", "status_top", NULL
);
1223 b
->status_format
= g_key_file_get_string (config
, "behavior", "status_format", NULL
);
1224 b
->status_background
= g_key_file_get_string (config
, "behavior", "status_background", NULL
);
1226 b
->fifo_dir
= g_key_file_get_value (config
, "behavior", "fifo_dir", NULL
);
1227 if (! b
->socket_dir
)
1228 b
->socket_dir
= g_key_file_get_value (config
, "behavior", "socket_dir", NULL
);
1229 keys
= g_key_file_get_keys (config
, "bindings", NULL
, NULL
);
1232 printf ("History handler: %s\n", (b
->history_handler
? b
->history_handler
: "disabled"));
1233 printf ("Download manager: %s\n", (b
->download_handler
? b
->download_handler
: "disabled"));
1234 printf ("Cookie handler: %s\n", (b
->cookie_handler
? b
->cookie_handler
: "disabled"));
1235 printf ("Fifo directory: %s\n", (b
->fifo_dir
? b
->fifo_dir
: "disabled"));
1236 printf ("Socket directory: %s\n", (b
->socket_dir
? b
->socket_dir
: "disabled"));
1237 printf ("Always insert mode: %s\n", (b
->always_insert_mode
? "TRUE" : "FALSE"));
1238 printf ("Show status: %s\n", (b
->show_status
? "TRUE" : "FALSE"));
1239 printf ("Status top: %s\n", (b
->status_top
? "TRUE" : "FALSE"));
1240 printf ("Modkey: %s\n", (b
->modkey
? b
->modkey
: "disabled"));
1241 printf ("Status format: %s\n", (b
->status_format
? b
->status_format
: "none"));
1246 //POSSIBLE MODKEY VALUES (COMBINATIONS CAN BE USED)
1247 gchar
* modkeyup
= g_utf8_strup (b
->modkey
, -1);
1248 if (g_strrstr (modkeyup
,"SHIFT") != NULL
) b
->modmask
|= GDK_SHIFT_MASK
; //the Shift key.
1249 if (g_strrstr (modkeyup
,"LOCK") != NULL
) b
->modmask
|= GDK_LOCK_MASK
; //a Lock key (depending on the modifier mapping of the X server this may either be CapsLock or ShiftLock).
1250 if (g_strrstr (modkeyup
,"CONTROL") != NULL
) b
->modmask
|= GDK_CONTROL_MASK
; //the Control key.
1251 if (g_strrstr (modkeyup
,"MOD1") != NULL
) b
->modmask
|= GDK_MOD1_MASK
; //the fourth modifier key (it depends on the modifier mapping of the X server which key is interpreted as this modifier, but normally it is the Alt key).
1252 if (g_strrstr (modkeyup
,"MOD2") != NULL
) b
->modmask
|= GDK_MOD2_MASK
; //the fifth modifier key (it depends on the modifier mapping of the X server which key is interpreted as this modifier).
1253 if (g_strrstr (modkeyup
,"MOD3") != NULL
) b
->modmask
|= GDK_MOD3_MASK
; //the sixth modifier key (it depends on the modifier mapping of the X server which key is interpreted as this modifier).
1254 if (g_strrstr (modkeyup
,"MOD4") != NULL
) b
->modmask
|= GDK_MOD4_MASK
; //the seventh modifier key (it depends on the modifier mapping of the X server which key is interpreted as this modifier).
1255 if (g_strrstr (modkeyup
,"MOD5") != NULL
) b
->modmask
|= GDK_MOD5_MASK
; //the eighth modifier key (it depends on the modifier mapping of the X server which key is interpreted as this modifier).
1256 if (g_strrstr (modkeyup
,"BUTTON1") != NULL
) b
->modmask
|= GDK_BUTTON1_MASK
; //the first mouse button.
1257 if (g_strrstr (modkeyup
,"BUTTON2") != NULL
) b
->modmask
|= GDK_BUTTON2_MASK
; //the second mouse button.
1258 if (g_strrstr (modkeyup
,"BUTTON3") != NULL
) b
->modmask
|= GDK_BUTTON3_MASK
; //the third mouse button.
1259 if (g_strrstr (modkeyup
,"BUTTON4") != NULL
) b
->modmask
|= GDK_BUTTON4_MASK
; //the fourth mouse button.
1260 if (g_strrstr (modkeyup
,"BUTTON5") != NULL
) b
->modmask
|= GDK_BUTTON5_MASK
; //the fifth mouse button.
1261 if (g_strrstr (modkeyup
,"SUPER") != NULL
) b
->modmask
|= GDK_SUPER_MASK
; //the Super modifier. Since 2.10
1262 if (g_strrstr (modkeyup
,"HYPER") != NULL
) b
->modmask
|= GDK_HYPER_MASK
; //the Hyper modifier. Since 2.10
1263 if (g_strrstr (modkeyup
,"META") != NULL
) b
->modmask
|= GDK_META_MASK
; //the Meta modifier. Since 2.10 */
1268 for (i
= 0; keys
[i
]; i
++) {
1269 gchar
*value
= g_key_file_get_string (config
, "bindings", keys
[i
], NULL
);
1271 add_binding(g_strstrip(keys
[i
]), value
);
1278 /* networking options */
1280 n
->proxy_url
= g_key_file_get_value (config
, "network", "proxy_server", NULL
);
1281 b
->http_debug
= g_key_file_get_integer (config
, "network", "http_debug", NULL
);
1282 n
->useragent
= g_key_file_get_value (config
, "network", "user-agent", NULL
);
1283 n
->max_conns
= g_key_file_get_integer (config
, "network", "max_conns", NULL
);
1284 n
->max_conns_host
= g_key_file_get_integer (config
, "network", "max_conns_per_host", NULL
);
1288 g_object_set(G_OBJECT(n
->soup_session
), SOUP_SESSION_PROXY_URI
, soup_uri_new(n
->proxy_url
), NULL
);
1291 if(!(b
->http_debug
<= 3)){
1293 fprintf(stderr
, "Wrong http_debug level, ignoring.\n");
1294 } else if (b
->http_debug
> 0) {
1295 n
->soup_logger
= soup_logger_new(b
->http_debug
, -1);
1296 soup_session_add_feature(n
->soup_session
, SOUP_SESSION_FEATURE(n
->soup_logger
));
1300 char* newagent
= malloc(1024);
1302 strcpy(newagent
, str_replace("%webkit-major%", itos(WEBKIT_MAJOR_VERSION
), n
->useragent
));
1303 strcpy(newagent
, str_replace("%webkit-minor%", itos(WEBKIT_MINOR_VERSION
), newagent
));
1304 strcpy(newagent
, str_replace("%webkit-micro%", itos(WEBKIT_MICRO_VERSION
), newagent
));
1306 if (uname (&s
->unameinfo
) == -1) {
1307 printf("Error getting uname info. Not replacing system-related user agent variables.\n");
1309 strcpy(newagent
, str_replace("%sysname%", s
->unameinfo
.sysname
, newagent
));
1310 strcpy(newagent
, str_replace("%nodename%", s
->unameinfo
.nodename
, newagent
));
1311 strcpy(newagent
, str_replace("%kernrel%", s
->unameinfo
.release
, newagent
));
1312 strcpy(newagent
, str_replace("%kernver%", s
->unameinfo
.version
, newagent
));
1313 strcpy(newagent
, str_replace("%arch-system%", s
->unameinfo
.machine
, newagent
));
1316 strcpy(newagent
, str_replace("%domainname%", s
->unameinfo
.domainname
, newagent
));
1320 strcpy(newagent
, str_replace("%arch-uzbl%", ARCH
, newagent
));
1321 strcpy(newagent
, str_replace("%commit%", COMMIT
, newagent
));
1323 n
->useragent
= malloc(1024);
1324 strcpy(n
->useragent
, newagent
);
1325 g_object_set(G_OBJECT(n
->soup_session
), SOUP_SESSION_USER_AGENT
, n
->useragent
, NULL
);
1328 if(n
->max_conns
>= 1){
1329 g_object_set(G_OBJECT(n
->soup_session
), SOUP_SESSION_MAX_CONNS
, n
->max_conns
, NULL
);
1332 if(n
->max_conns_host
>= 1){
1333 g_object_set(G_OBJECT(n
->soup_session
), SOUP_SESSION_MAX_CONNS_PER_HOST
, n
->max_conns_host
, NULL
);
1336 printf("Proxy configured: %s\n", n
->proxy_url
? n
->proxy_url
: "none");
1337 printf("HTTP logging level: %d\n", b
->http_debug
);
1338 printf("User-agent: %s\n", n
->useragent
? n
->useragent
: "default");
1339 printf("Maximum connections: %d\n", n
->max_conns
? n
->max_conns
: 0);
1340 printf("Maximum connections per host: %d\n", n
->max_conns_host
? n
->max_conns_host
: 0);
1344 if(b
->cookie_handler
){
1345 /* ck = soup_cookie_jar_new(); */
1346 /* soup_session_add_feature(soup_session, SOUP_SESSION_FEATURE(ck)); */
1347 /* g_signal_connect(ck, "changed", G_CALLBACK(cookie_recieved_action), NULL); */
1348 g_signal_connect(n
->soup_session
, "request-queued", G_CALLBACK(handle_cookies
), NULL
);
1353 static void handle_cookies (SoupSession
*session
, SoupMessage
*msg
, gpointer user_data
){
1356 gchar
* stdout
= NULL
;
1357 soup_message_add_header_handler(msg
, "got-headers", "Set-Cookie", G_CALLBACK(save_cookies
), NULL
);
1358 GString
* args
= g_string_new ("");
1359 SoupURI
* soup_uri
= soup_message_get_uri(msg
);
1360 g_string_printf (args
, "GET %s %s", soup_uri
->host
, soup_uri
->path
);
1361 run_command_sync(uzbl
.behave
.cookie_handler
, args
->str
, &stdout
);
1363 soup_message_headers_replace (msg
->request_headers
, "Cookie", stdout
);
1365 g_string_free(args
, TRUE
);
1369 save_cookies (SoupMessage
*msg
, gpointer user_data
){
1373 for (ck
= soup_cookies_from_response(msg
); ck
; ck
= ck
->next
){
1374 cookie
= soup_cookie_to_set_cookie_header(ck
->data
);
1375 GString
* args
= g_string_new ("");
1376 SoupURI
* soup_uri
= soup_message_get_uri(msg
);
1377 g_string_printf (args
, "PUT %s %s \"%s\"", soup_uri
->host
, soup_uri
->path
, cookie
);
1378 run_command_async(uzbl
.behave
.cookie_handler
, args
->str
);
1379 g_string_free(args
, TRUE
);
1386 main (int argc
, char* argv
[]) {
1387 gtk_init (&argc
, &argv
);
1388 if (!g_thread_supported ())
1389 g_thread_init (NULL
);
1391 printf("Uzbl start location: %s\n", argv
[0]);
1392 strcpy(uzbl
.state
.executable_path
,argv
[0]);
1394 strcat ((char *) XDG_CONFIG_HOME_default
, getenv ("HOME"));
1395 strcat ((char *) XDG_CONFIG_HOME_default
, "/.config");
1397 GError
*error
= NULL
;
1398 GOptionContext
* context
= g_option_context_new ("- some stuff here maybe someday");
1399 g_option_context_add_main_entries (context
, entries
, NULL
);
1400 g_option_context_add_group (context
, gtk_get_option_group (TRUE
));
1401 g_option_context_parse (context
, &argc
, &argv
, &error
);
1402 /* initialize hash table */
1403 uzbl
.bindings
= g_hash_table_new_full(g_str_hash
, g_str_equal
, g_free
, free_action
);
1405 uzbl
.net
.soup_session
= webkit_get_default_session();
1406 uzbl
.state
.keycmd
= g_string_new("");
1411 if (uzbl
.behave
.always_insert_mode
)
1412 uzbl
.behave
.insert_mode
= TRUE
;
1414 GtkWidget
* vbox
= gtk_vbox_new (FALSE
, 0);
1415 if (uzbl
.behave
.status_top
)
1416 gtk_box_pack_start (GTK_BOX (vbox
), create_mainbar (), FALSE
, TRUE
, 0);
1417 gtk_box_pack_start (GTK_BOX (vbox
), create_browser (), TRUE
, TRUE
, 0);
1418 if (!uzbl
.behave
.status_top
)
1419 gtk_box_pack_start (GTK_BOX (vbox
), create_mainbar (), FALSE
, TRUE
, 0);
1421 uzbl
.gui
.main_window
= create_window ();
1422 gtk_container_add (GTK_CONTAINER (uzbl
.gui
.main_window
), vbox
);
1424 load_uri (uzbl
.gui
.web_view
, uzbl
.state
.uri
);
1426 gtk_widget_grab_focus (GTK_WIDGET (uzbl
.gui
.web_view
));
1427 gtk_widget_show_all (uzbl
.gui
.main_window
);
1428 uzbl
.xwin
= GDK_WINDOW_XID (GTK_WIDGET (uzbl
.gui
.main_window
)->window
);
1429 printf("window_id %i\n",(int) uzbl
.xwin
);
1430 printf("pid %i\n", getpid ());
1431 printf("name: %s\n", uzbl
.state
.instance_name
);
1433 uzbl
.gui
.scbar_v
= (GtkScrollbar
*) gtk_vscrollbar_new (NULL
);
1434 uzbl
.gui
.bar_v
= gtk_range_get_adjustment((GtkRange
*) uzbl
.gui
.scbar_v
);
1435 uzbl
.gui
.scbar_h
= (GtkScrollbar
*) gtk_hscrollbar_new (NULL
);
1436 uzbl
.gui
.bar_h
= gtk_range_get_adjustment((GtkRange
*) uzbl
.gui
.scbar_h
);
1437 gtk_widget_set_scroll_adjustments ((GtkWidget
*) uzbl
.gui
.web_view
, uzbl
.gui
.bar_h
, uzbl
.gui
.bar_v
);
1440 if(setup_signal(SIGTERM
, catch_sigterm
) == SIG_ERR
)
1441 fprintf(stderr
, "uzbl: error hooking SIGTERM\n");
1447 if (!uzbl
.behave
.status_format
)
1448 uzbl
.behave
.status_format
= STATUS_DEFAULT
;
1449 if (!uzbl
.behave
.show_status
)
1450 gtk_widget_hide(uzbl
.gui
.mainbar
);
1455 make_var_to_name_hash();
1457 if (uzbl
.behave
.fifo_dir
)
1459 if (uzbl
.behave
.socket_dir
)
1465 return EXIT_SUCCESS
;
1468 /* vi: set et ts=4: */