From c8d71fa5538003a48d367fea5a1d8b463b98ede3 Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 19 Oct 2009 02:13:15 +0200 Subject: Add simple commandline history plugin to EM. --- examples/data/uzbl/plugins/history.py | 124 ++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 examples/data/uzbl/plugins/history.py diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py new file mode 100644 index 0000000..5ea2794 --- /dev/null +++ b/examples/data/uzbl/plugins/history.py @@ -0,0 +1,124 @@ +__export__ = ['get_history'] +UZBLS = {} + +import random + +class History(object): + def __init__(self): + self._commands = [] + self.cursor = None + self.__temp_tail = False + self.search_key = None + + def prev(self): + if self.cursor is None: + self.cursor = len(self._commands) - 1 + else: + self.cursor -= 1 + + if self.search_key: + while self.cursor >= 0 and self.search_key not in self._commands[self.cursor]: + self.cursor -= 1 + + if self.cursor < 0 or len(self._commands) == 0: + self.cursor = -1 + return random.choice(end_messages) + + return self._commands[self.cursor] + + def next(self): + if self.cursor is None: + return '' + + self.cursor += 1 + + if self.search_key: + while self.cursor < len(self._commands) and self.search_key not in self._commands[self.cursor]: + self.cursor += 1 + + if self.cursor >= len(self._commands) - (1 if self.__temp_tail else 0): + self.cursor = None + self.search_key = None + + if self.__temp_tail: + print 'popping temporary' + self.__temp_tail = False + return self._commands.pop() + return '' + + return self._commands[self.cursor] + + def search(self, key): + self.search_key = key + return self.prev() + + def add(self, cmd): + if self.__temp_tail: + self._commands.pop() + self.__temp_tail = False + + self._commands.append(cmd) + self.cursor = None + self.search_key = None + + def add_temporary(self, cmd): + assert not self.__temp_tail + + self._commands.append(cmd) + self.__temp_tail = True + self.cursor = len(self._commands) - 1 + + print 'adding temporary', self + + def __str__(self): + return "(History %s, %s)" % (self.cursor, str(self._commands)) + +def get_history(uzbl): + return UZBLS[uzbl] + +def add_instance(uzbl, *args): + UZBLS[uzbl] = History() + +def del_instance(uzbl, *args): + if uzbl in UZBLS: + del UZBLS[uzbl] + +def keycmd_exec(uzbl, keylet): + history = get_history(uzbl) + cmd = keylet.key_cmd() + if cmd: + history.add(cmd) + +def history_prev(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().key_cmd() + if history.cursor is None and cmd: + history.add_temporary(cmd) + + uzbl.set_keycmd(history.prev()) + print 'PREV', history + +def history_next(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().key_cmd() + + uzbl.set_keycmd(history.next()) + print 'NEXT', history + +def history_search(uzbl, key): + history = get_history(uzbl) + uzbl.set_keycmd(history.search(key)) + print 'SEARCH', history + +end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') + +def init(uzbl): + connects = {'INSTANCE_START': add_instance, + 'INSTANCE_EXIT': del_instance, + 'KEYCMD_EXEC': keycmd_exec, + 'HISTORY_PREV': history_prev, + 'HISTORY_NEXT': history_next, + 'HISTORY_SEARCH': history_search + } + + uzbl.connect_dict(connects) -- cgit v1.2.3 From 830e075e51528c03db3fb9e0206c2934fe012c8e Mon Sep 17 00:00:00 2001 From: David Keijser Date: Sun, 25 Oct 2009 17:47:28 +0100 Subject: update history plugin to work with latest EM. --- examples/data/uzbl/plugins/history.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index 5ea2794..595600e 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -85,13 +85,13 @@ def del_instance(uzbl, *args): def keycmd_exec(uzbl, keylet): history = get_history(uzbl) - cmd = keylet.key_cmd() + cmd = keylet.get_keycmd() if cmd: history.add(cmd) def history_prev(uzbl, _x): history = get_history(uzbl) - cmd = uzbl.get_keylet().key_cmd() + cmd = uzbl.get_keylet().get_keycmd() if history.cursor is None and cmd: history.add_temporary(cmd) @@ -100,7 +100,7 @@ def history_prev(uzbl, _x): def history_next(uzbl, _x): history = get_history(uzbl) - cmd = uzbl.get_keylet().key_cmd() + cmd = uzbl.get_keylet().get_keycmd() uzbl.set_keycmd(history.next()) print 'NEXT', history -- cgit v1.2.3 From 4f70b20a578d2618ca066f200f5b97d9a3f61220 Mon Sep 17 00:00:00 2001 From: keis Date: Thu, 5 Nov 2009 20:11:10 +0100 Subject: share history among instances. --- examples/data/uzbl/plugins/history.py | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index 595600e..7855014 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -3,50 +3,54 @@ UZBLS = {} import random +shared_history = [] + class History(object): def __init__(self): - self._commands = [] + self._temporary = [] self.cursor = None self.__temp_tail = False self.search_key = None def prev(self): + commands = shared_history + self._temporary if self.cursor is None: - self.cursor = len(self._commands) - 1 + self.cursor = len(commands) - 1 else: self.cursor -= 1 if self.search_key: - while self.cursor >= 0 and self.search_key not in self._commands[self.cursor]: + while self.cursor >= 0 and self.search_key not in commands[self.cursor]: self.cursor -= 1 - if self.cursor < 0 or len(self._commands) == 0: + if self.cursor < 0 or len(commands) == 0: self.cursor = -1 return random.choice(end_messages) - return self._commands[self.cursor] + return commands[self.cursor] def next(self): + commands = shared_history + self._temporary if self.cursor is None: return '' self.cursor += 1 if self.search_key: - while self.cursor < len(self._commands) and self.search_key not in self._commands[self.cursor]: + while self.cursor < len(commands) and self.search_key not in commands[self.cursor]: self.cursor += 1 - if self.cursor >= len(self._commands) - (1 if self.__temp_tail else 0): + if self.cursor >= len(commands) - (1 if self.__temp_tail else 0): self.cursor = None self.search_key = None if self.__temp_tail: print 'popping temporary' self.__temp_tail = False - return self._commands.pop() + return self._temporary.pop() return '' - return self._commands[self.cursor] + return commands[self.cursor] def search(self, key): self.search_key = key @@ -54,24 +58,24 @@ class History(object): def add(self, cmd): if self.__temp_tail: - self._commands.pop() + self._temporary.pop() self.__temp_tail = False - self._commands.append(cmd) + shared_history.append(cmd) self.cursor = None self.search_key = None def add_temporary(self, cmd): assert not self.__temp_tail - self._commands.append(cmd) + self._temporary.append(cmd) self.__temp_tail = True - self.cursor = len(self._commands) - 1 + self.cursor = len(self._temporary) + len(shared_history) - 1 print 'adding temporary', self def __str__(self): - return "(History %s, %s)" % (self.cursor, str(self._commands)) + return "(History %s)" % (self.cursor) def get_history(uzbl): return UZBLS[uzbl] -- cgit v1.2.3 From 039caee15ad50e042d680a975ce6b066b3bdd19a Mon Sep 17 00:00:00 2001 From: keis Date: Thu, 5 Nov 2009 20:20:20 +0100 Subject: refactor history plugin. --- examples/data/uzbl/plugins/history.py | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index 7855014..f514f36 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -13,67 +13,70 @@ class History(object): self.search_key = None def prev(self): - commands = shared_history + self._temporary if self.cursor is None: - self.cursor = len(commands) - 1 + self.cursor = len(self) - 1 else: self.cursor -= 1 if self.search_key: - while self.cursor >= 0 and self.search_key not in commands[self.cursor]: + while self.cursor >= 0 and self.search_key not in self[self.cursor]: self.cursor -= 1 - if self.cursor < 0 or len(commands) == 0: + if self.cursor < 0 or len(self) == 0: self.cursor = -1 return random.choice(end_messages) - return commands[self.cursor] + return self[self.cursor] def next(self): - commands = shared_history + self._temporary if self.cursor is None: return '' self.cursor += 1 if self.search_key: - while self.cursor < len(commands) and self.search_key not in commands[self.cursor]: + while self.cursor < len(self) and self.search_key not in self[self.cursor]: self.cursor += 1 - if self.cursor >= len(commands) - (1 if self.__temp_tail else 0): + if self.cursor >= len(shared_history): self.cursor = None self.search_key = None - if self.__temp_tail: + if self._temporary: print 'popping temporary' - self.__temp_tail = False return self._temporary.pop() return '' - return commands[self.cursor] + return self[self.cursor] def search(self, key): self.search_key = key return self.prev() def add(self, cmd): - if self.__temp_tail: + if self._temporary: self._temporary.pop() - self.__temp_tail = False shared_history.append(cmd) self.cursor = None self.search_key = None def add_temporary(self, cmd): - assert not self.__temp_tail + assert not self._temporary self._temporary.append(cmd) - self.__temp_tail = True - self.cursor = len(self._temporary) + len(shared_history) - 1 + self.cursor = len(self) - 1 print 'adding temporary', self + def __getitem__(self, i): + if i < len(shared_history): + return shared_history[i] + return self._temporary[i-len(shared_history)+1] + + def __len__(self): + return len(shared_history) + len(self._temporary) + def __str__(self): return "(History %s)" % (self.cursor) -- cgit v1.2.3 From b5042ed71d57e006bad8ac2b6fd02a5c0ece70be Mon Sep 17 00:00:00 2001 From: keis Date: Thu, 5 Nov 2009 20:21:32 +0100 Subject: add example history bindings. --- examples/config/uzbl/config | 2 ++ 1 file changed, 2 insertions(+) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 8a2ad87..00c6c14 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -213,6 +213,8 @@ set formfiller = spawn @scripts_dir/formfiller @bind du = event APPEND_KEYCMD \@uri @bind dt = event APPEND_KEYCMD \@TITLE +@bind = request HISTORY_PREV +@bind = request HISTORY_NEXT # === command editing configuration ========================================== -- cgit v1.2.3 From 4e16343b4b30c1ff24c46e75945f092732413deb Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 8 Dec 2009 17:37:23 +0100 Subject: maintain separate histories for each prompt --- examples/data/uzbl/plugins/history.py | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py index f514f36..4467e5d 100644 --- a/examples/data/uzbl/plugins/history.py +++ b/examples/data/uzbl/plugins/history.py @@ -3,11 +3,12 @@ UZBLS = {} import random -shared_history = [] +shared_history = {'':[]} class History(object): def __init__(self): self._temporary = [] + self.prompt = '' self.cursor = None self.__temp_tail = False self.search_key = None @@ -38,7 +39,7 @@ class History(object): while self.cursor < len(self) and self.search_key not in self[self.cursor]: self.cursor += 1 - if self.cursor >= len(shared_history): + if self.cursor >= len(shared_history[self.prompt]): self.cursor = None self.search_key = None @@ -49,6 +50,13 @@ class History(object): return self[self.cursor] + def change_prompt(self, prompt): + self.prompt = prompt + self._temporary = [] + self.__temp_tail = False + if prompt not in shared_history: + shared_history[prompt] = [] + def search(self, key): self.search_key = key return self.prev() @@ -57,7 +65,7 @@ class History(object): if self._temporary: self._temporary.pop() - shared_history.append(cmd) + shared_history[self.prompt].append(cmd) self.cursor = None self.search_key = None @@ -70,17 +78,20 @@ class History(object): print 'adding temporary', self def __getitem__(self, i): - if i < len(shared_history): - return shared_history[i] + if i < len(shared_history[self.prompt]): + return shared_history[self.prompt][i] return self._temporary[i-len(shared_history)+1] def __len__(self): - return len(shared_history) + len(self._temporary) + return len(shared_history[self.prompt]) + len(self._temporary) def __str__(self): return "(History %s)" % (self.cursor) def get_history(uzbl): + if uzbl not in UZBLS: + add_instance(uzbl) + return UZBLS[uzbl] def add_instance(uzbl, *args): @@ -96,6 +107,11 @@ def keycmd_exec(uzbl, keylet): if cmd: history.add(cmd) +def config_changed(uzbl, key, value): + if key == 'keycmd_prompt': + history = get_history(uzbl) + history.change_prompt(value) + def history_prev(uzbl, _x): history = get_history(uzbl) cmd = uzbl.get_keylet().get_keycmd() @@ -123,6 +139,7 @@ def init(uzbl): connects = {'INSTANCE_START': add_instance, 'INSTANCE_EXIT': del_instance, 'KEYCMD_EXEC': keycmd_exec, + 'CONFIG_CHANGED': config_changed, 'HISTORY_PREV': history_prev, 'HISTORY_NEXT': history_next, 'HISTORY_SEARCH': history_search -- cgit v1.2.3 From 5930439a3003f1d77d71bca440bbe918e7c657d9 Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 8 Dec 2009 18:47:42 +0100 Subject: use event instead of request for history prev/next --- examples/config/uzbl/config | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/config/uzbl/config b/examples/config/uzbl/config index 1ef1758..e9f7f8d 100644 --- a/examples/config/uzbl/config +++ b/examples/config/uzbl/config @@ -248,8 +248,8 @@ set formfiller = spawn @scripts_dir/formfiller @bind du = event APPEND_KEYCMD \@uri @bind dt = event APPEND_KEYCMD \@TITLE -@bind = request HISTORY_PREV -@bind = request HISTORY_NEXT +@bind = event HISTORY_PREV +@bind = event HISTORY_NEXT # === command editing configuration ========================================== -- cgit v1.2.3 From c37f739ce5b51091732cec0452e8035fc187c096 Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 4 Apr 2010 22:27:11 +0200 Subject: move history plugin --- examples/data/plugins/history.py | 148 ++++++++++++++++++++++++++++++++++ examples/data/uzbl/plugins/history.py | 148 ---------------------------------- 2 files changed, 148 insertions(+), 148 deletions(-) create mode 100644 examples/data/plugins/history.py delete mode 100644 examples/data/uzbl/plugins/history.py diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py new file mode 100644 index 0000000..4467e5d --- /dev/null +++ b/examples/data/plugins/history.py @@ -0,0 +1,148 @@ +__export__ = ['get_history'] +UZBLS = {} + +import random + +shared_history = {'':[]} + +class History(object): + def __init__(self): + self._temporary = [] + self.prompt = '' + self.cursor = None + self.__temp_tail = False + self.search_key = None + + def prev(self): + if self.cursor is None: + self.cursor = len(self) - 1 + else: + self.cursor -= 1 + + if self.search_key: + while self.cursor >= 0 and self.search_key not in self[self.cursor]: + self.cursor -= 1 + + if self.cursor < 0 or len(self) == 0: + self.cursor = -1 + return random.choice(end_messages) + + return self[self.cursor] + + def next(self): + if self.cursor is None: + return '' + + self.cursor += 1 + + if self.search_key: + while self.cursor < len(self) and self.search_key not in self[self.cursor]: + self.cursor += 1 + + if self.cursor >= len(shared_history[self.prompt]): + self.cursor = None + self.search_key = None + + if self._temporary: + print 'popping temporary' + return self._temporary.pop() + return '' + + return self[self.cursor] + + def change_prompt(self, prompt): + self.prompt = prompt + self._temporary = [] + self.__temp_tail = False + if prompt not in shared_history: + shared_history[prompt] = [] + + def search(self, key): + self.search_key = key + return self.prev() + + def add(self, cmd): + if self._temporary: + self._temporary.pop() + + shared_history[self.prompt].append(cmd) + self.cursor = None + self.search_key = None + + def add_temporary(self, cmd): + assert not self._temporary + + self._temporary.append(cmd) + self.cursor = len(self) - 1 + + print 'adding temporary', self + + def __getitem__(self, i): + if i < len(shared_history[self.prompt]): + return shared_history[self.prompt][i] + return self._temporary[i-len(shared_history)+1] + + def __len__(self): + return len(shared_history[self.prompt]) + len(self._temporary) + + def __str__(self): + return "(History %s)" % (self.cursor) + +def get_history(uzbl): + if uzbl not in UZBLS: + add_instance(uzbl) + + return UZBLS[uzbl] + +def add_instance(uzbl, *args): + UZBLS[uzbl] = History() + +def del_instance(uzbl, *args): + if uzbl in UZBLS: + del UZBLS[uzbl] + +def keycmd_exec(uzbl, keylet): + history = get_history(uzbl) + cmd = keylet.get_keycmd() + if cmd: + history.add(cmd) + +def config_changed(uzbl, key, value): + if key == 'keycmd_prompt': + history = get_history(uzbl) + history.change_prompt(value) + +def history_prev(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().get_keycmd() + if history.cursor is None and cmd: + history.add_temporary(cmd) + + uzbl.set_keycmd(history.prev()) + print 'PREV', history + +def history_next(uzbl, _x): + history = get_history(uzbl) + cmd = uzbl.get_keylet().get_keycmd() + + uzbl.set_keycmd(history.next()) + print 'NEXT', history + +def history_search(uzbl, key): + history = get_history(uzbl) + uzbl.set_keycmd(history.search(key)) + print 'SEARCH', history + +end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') + +def init(uzbl): + connects = {'INSTANCE_START': add_instance, + 'INSTANCE_EXIT': del_instance, + 'KEYCMD_EXEC': keycmd_exec, + 'CONFIG_CHANGED': config_changed, + 'HISTORY_PREV': history_prev, + 'HISTORY_NEXT': history_next, + 'HISTORY_SEARCH': history_search + } + + uzbl.connect_dict(connects) diff --git a/examples/data/uzbl/plugins/history.py b/examples/data/uzbl/plugins/history.py deleted file mode 100644 index 4467e5d..0000000 --- a/examples/data/uzbl/plugins/history.py +++ /dev/null @@ -1,148 +0,0 @@ -__export__ = ['get_history'] -UZBLS = {} - -import random - -shared_history = {'':[]} - -class History(object): - def __init__(self): - self._temporary = [] - self.prompt = '' - self.cursor = None - self.__temp_tail = False - self.search_key = None - - def prev(self): - if self.cursor is None: - self.cursor = len(self) - 1 - else: - self.cursor -= 1 - - if self.search_key: - while self.cursor >= 0 and self.search_key not in self[self.cursor]: - self.cursor -= 1 - - if self.cursor < 0 or len(self) == 0: - self.cursor = -1 - return random.choice(end_messages) - - return self[self.cursor] - - def next(self): - if self.cursor is None: - return '' - - self.cursor += 1 - - if self.search_key: - while self.cursor < len(self) and self.search_key not in self[self.cursor]: - self.cursor += 1 - - if self.cursor >= len(shared_history[self.prompt]): - self.cursor = None - self.search_key = None - - if self._temporary: - print 'popping temporary' - return self._temporary.pop() - return '' - - return self[self.cursor] - - def change_prompt(self, prompt): - self.prompt = prompt - self._temporary = [] - self.__temp_tail = False - if prompt not in shared_history: - shared_history[prompt] = [] - - def search(self, key): - self.search_key = key - return self.prev() - - def add(self, cmd): - if self._temporary: - self._temporary.pop() - - shared_history[self.prompt].append(cmd) - self.cursor = None - self.search_key = None - - def add_temporary(self, cmd): - assert not self._temporary - - self._temporary.append(cmd) - self.cursor = len(self) - 1 - - print 'adding temporary', self - - def __getitem__(self, i): - if i < len(shared_history[self.prompt]): - return shared_history[self.prompt][i] - return self._temporary[i-len(shared_history)+1] - - def __len__(self): - return len(shared_history[self.prompt]) + len(self._temporary) - - def __str__(self): - return "(History %s)" % (self.cursor) - -def get_history(uzbl): - if uzbl not in UZBLS: - add_instance(uzbl) - - return UZBLS[uzbl] - -def add_instance(uzbl, *args): - UZBLS[uzbl] = History() - -def del_instance(uzbl, *args): - if uzbl in UZBLS: - del UZBLS[uzbl] - -def keycmd_exec(uzbl, keylet): - history = get_history(uzbl) - cmd = keylet.get_keycmd() - if cmd: - history.add(cmd) - -def config_changed(uzbl, key, value): - if key == 'keycmd_prompt': - history = get_history(uzbl) - history.change_prompt(value) - -def history_prev(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() - if history.cursor is None and cmd: - history.add_temporary(cmd) - - uzbl.set_keycmd(history.prev()) - print 'PREV', history - -def history_next(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() - - uzbl.set_keycmd(history.next()) - print 'NEXT', history - -def history_search(uzbl, key): - history = get_history(uzbl) - uzbl.set_keycmd(history.search(key)) - print 'SEARCH', history - -end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') - -def init(uzbl): - connects = {'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, - 'KEYCMD_EXEC': keycmd_exec, - 'CONFIG_CHANGED': config_changed, - 'HISTORY_PREV': history_prev, - 'HISTORY_NEXT': history_next, - 'HISTORY_SEARCH': history_search - } - - uzbl.connect_dict(connects) -- cgit v1.2.3 From 14bce08a78c86e8cca7a6ca4b64d3692fa2782b5 Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 30 Nov 2010 18:35:20 +0100 Subject: make history plugin work with new EM --- examples/data/plugins/history.py | 65 ++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 42 deletions(-) diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 4467e5d..886cbe0 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -1,12 +1,10 @@ -__export__ = ['get_history'] -UZBLS = {} - import random shared_history = {'':[]} class History(object): - def __init__(self): + def __init__(self, uzbl): + self.uzbl = uzbl self._temporary = [] self.prompt = '' self.cursor = None @@ -86,63 +84,46 @@ class History(object): return len(shared_history[self.prompt]) + len(self._temporary) def __str__(self): - return "(History %s)" % (self.cursor) - -def get_history(uzbl): - if uzbl not in UZBLS: - add_instance(uzbl) - - return UZBLS[uzbl] - -def add_instance(uzbl, *args): - UZBLS[uzbl] = History() - -def del_instance(uzbl, *args): - if uzbl in UZBLS: - del UZBLS[uzbl] + return "(History %s, %s)" % (self.cursor, self.prompt) def keycmd_exec(uzbl, keylet): - history = get_history(uzbl) cmd = keylet.get_keycmd() if cmd: - history.add(cmd) - -def config_changed(uzbl, key, value): - if key == 'keycmd_prompt': - history = get_history(uzbl) - history.change_prompt(value) + uzbl.history.add(cmd) def history_prev(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() - if history.cursor is None and cmd: - history.add_temporary(cmd) + cmd = uzbl.keylet.get_keycmd() + if uzbl.history.cursor is None and cmd: + uzbl.history.add_temporary(cmd) - uzbl.set_keycmd(history.prev()) - print 'PREV', history + uzbl.set_keycmd(uzbl.history.prev()) + uzbl.logger.debug('PREV %s' % uzbl.history) def history_next(uzbl, _x): - history = get_history(uzbl) - cmd = uzbl.get_keylet().get_keycmd() + cmd = uzbl.keylet.get_keycmd() - uzbl.set_keycmd(history.next()) - print 'NEXT', history + uzbl.set_keycmd(uzbl.history.next()) + uzbl.logger.debug('NEXT %s' % uzbl.history) def history_search(uzbl, key): - history = get_history(uzbl) uzbl.set_keycmd(history.search(key)) - print 'SEARCH', history + uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history)) end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') +# plugin init hook def init(uzbl): - connects = {'INSTANCE_START': add_instance, - 'INSTANCE_EXIT': del_instance, + connect_dict(uzbl, { 'KEYCMD_EXEC': keycmd_exec, - 'CONFIG_CHANGED': config_changed, 'HISTORY_PREV': history_prev, 'HISTORY_NEXT': history_next, 'HISTORY_SEARCH': history_search - } + }) + + export_dict(uzbl, { + 'history' : History(uzbl) + }) - uzbl.connect_dict(connects) +# plugin after hook +def after(uzbl): + uzbl.on_set('keycmd_prompt', lambda uzbl, k, v: uzbl.history.change_prompt(v)) -- cgit v1.2.3 From 7cf3fb88d1e094da5b516699a61d5e589c039e8f Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 30 Nov 2010 19:25:34 +0100 Subject: disable odd clear of keycmd was breaking history of prompts, for what I can tell no good reason --- examples/data/plugins/bind.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index 5b13476..bf693b3 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -421,7 +421,8 @@ def match_and_exec(uzbl, bind, depth, keylet, bindlet): if not has_args or on_exec: del uzbl.config['mode'] bindlet.reset() - uzbl.clear_current() + # cleared by keycmd_exec_current, why is this here? breaks history + #uzbl.clear_current() return True -- cgit v1.2.3 From 32800e94c6667c8f44dfe2178115049c280de339 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 27 Dec 2010 19:55:44 -0700 Subject: remove example cookie daemons --- Makefile | 16 +- examples/data/scripts/uzbl-cookie-daemon | 677 ------------------------------- examples/uzbl-cookie-manager.c | 381 ----------------- src/uzbl-browser | 7 - 4 files changed, 3 insertions(+), 1078 deletions(-) delete mode 100755 examples/data/scripts/uzbl-cookie-daemon delete mode 100644 examples/uzbl-cookie-manager.c diff --git a/Makefile b/Makefile index e4d1b42..2b1a70a 100644 --- a/Makefile +++ b/Makefile @@ -10,7 +10,7 @@ SRC = $(wildcard src/*.c) HEAD = $(wildcard src/*.h) OBJ = $(foreach obj, $(SRC:.c=.o), $(notdir $(obj))) -all: uzbl-browser uzbl-cookie-manager +all: uzbl-browser VPATH:=src @@ -24,11 +24,7 @@ uzbl-core: ${OBJ} @echo -e "\n${CC} -o $@ ${OBJ} ${UZBL_LDFLAGS}" @${CC} -o $@ ${OBJ} ${UZBL_LDFLAGS} -uzbl-cookie-manager: examples/uzbl-cookie-manager.o src/util.o - @echo -e "\n${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS} ${shell pkg-config --libs glib-2.0 libsoup-2.4}" - @${CC} -o $@ uzbl-cookie-manager.o util.o ${LDFLAGS} $(shell pkg-config --libs glib-2.0 libsoup-2.4) - -uzbl-browser: uzbl-core uzbl-cookie-manager +uzbl-browser: uzbl-core # packagers, set DESTDIR to your "package directory" and PREFIX to the prefix you want to have on the end-user system # end-users who build from source: don't care about DESTDIR, update PREFIX if you want to @@ -66,10 +62,8 @@ test-uzbl-browser-sandbox: uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data cp -np ./misc/env.sh ./sandbox/env.sh - -source ./sandbox/env.sh && uzbl-cookie-manager -v -source ./sandbox/env.sh && uzbl-event-manager restart -avv source ./sandbox/env.sh && uzbl-browser --uri http://www.uzbl.org --verbose - kill `cat ./sandbox/home/.cache/uzbl/cookie_daemon_socket.pid` source ./sandbox/env.sh && uzbl-event-manager stop -ivv make DESTDIR=./sandbox uninstall rm -rf ./sandbox/usr @@ -79,17 +73,14 @@ test-uzbl-tabbed-sandbox: uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-uzbl-browser make DESTDIR=./sandbox RUN_PREFIX=`pwd`/sandbox/usr/local install-example-data cp -np ./misc/env.sh ./sandbox/env.sh - -source ./sandbox/env.sh && uzbl-cookie-manager -v -source ./sandbox/env.sh && uzbl-event-manager restart -avv source ./sandbox/env.sh && ./sandbox/home/.local/share/uzbl/scripts/uzbl-tabbed - kill `cat ./sandbox/home/.cache/uzbl/cookie_daemon_socket.pid` source ./sandbox/env.sh && uzbl-event-manager stop -ivv make DESTDIR=./sandbox uninstall rm -rf ./sandbox/usr clean: rm -f uzbl-core - rm -f uzbl-cookie-manager rm -f uzbl-core.o rm -f events.o rm -f callbacks.o @@ -121,9 +112,8 @@ install-uzbl-core: all install-dirs chmod 755 $(INSTALLDIR)/share/uzbl/examples/data/scripts/* install -m755 uzbl-core $(INSTALLDIR)/bin/uzbl-core -install-uzbl-browser: uzbl-cookie-manager install-dirs +install-uzbl-browser: install-dirs install -m755 src/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser - install -m755 uzbl-cookie-manager $(INSTALLDIR)/bin/uzbl-cookie-manager install -m755 examples/data/scripts/uzbl-event-manager $(INSTALLDIR)/bin/uzbl-event-manager mv $(INSTALLDIR)/bin/uzbl-browser $(INSTALLDIR)/bin/uzbl-browser.bak sed 's#^PREFIX=.*#PREFIX=$(RUN_PREFIX)#' < $(INSTALLDIR)/bin/uzbl-browser.bak > $(INSTALLDIR)/bin/uzbl-browser diff --git a/examples/data/scripts/uzbl-cookie-daemon b/examples/data/scripts/uzbl-cookie-daemon deleted file mode 100755 index 0b9bef9..0000000 --- a/examples/data/scripts/uzbl-cookie-daemon +++ /dev/null @@ -1,677 +0,0 @@ -#!/usr/bin/env python - -# The Python Cookie Daemon for Uzbl. -# Copyright (c) 2009, Tom Adams -# Copyright (c) 2009, Dieter Plaetinck -# Copyright (c) 2009, Mason Larobina -# Copyright (c) 2009, Michael Fiano -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -''' -The Python Cookie Daemon -======================== - -This daemon is a re-write of the original cookies.py script found in uzbl's -master branch. This script provides more functionality than the original -cookies.py by adding numerous command line options to specify different cookie -jar locations, socket locations, verbose output, etc. This functionality is -very useful as it allows you to run multiple daemons at once serving cookies -to different groups of uzbl instances as required. - -Keeping up to date -================== - -Check the cookie daemon uzbl-wiki page for more information on where to -find the latest version of the cookie_daemon.py - - http://www.uzbl.org/wiki/cookie_daemon.py - -Command line options -==================== - -Use the following command to get a full list of the cookie_daemon.py command -line options: - - ./cookie_daemon.py --help - -Talking with uzbl -================= - -In order to get uzbl to talk to a running cookie daemon you add the following -to your uzbl config: - - set cookie_handler = talk_to_socket $XDG_CACHE_HOME/uzbl/cookie_daemon_socket - -Or if you prefer using the $HOME variable: - - set cookie_handler = talk_to_socket $HOME/.cache/uzbl/cookie_daemon_socket - -Todo list -========= - - - Use a pid file to make force killing a running daemon possible. - -Reporting bugs / getting help -============================= - -The best way to report bugs and or get help with the cookie daemon is to -contact the maintainers it the #uzbl irc channel found on the Freenode IRC -network (irc.freenode.org). -''' - -import cookielib -import os -import sys -import urllib2 -import select -import socket -import time -import atexit -from traceback import print_exc -from signal import signal, SIGTERM -from optparse import OptionParser -from os.path import join - -try: - import cStringIO as StringIO - -except ImportError: - import StringIO - - -# ============================================================================ -# ::: Default configuration section :::::::::::::::::::::::::::::::::::::::::: -# ============================================================================ - -def xdghome(key, default): - '''Attempts to use the environ XDG_*_HOME paths if they exist otherwise - use $HOME and the default path.''' - - xdgkey = "XDG_%s_HOME" % key - if xdgkey in os.environ.keys() and os.environ[xdgkey]: - return os.environ[xdgkey] - - return join(os.environ['HOME'], default) - -# Setup xdg paths. -CACHE_DIR = join(xdghome('CACHE', '.cache/'), 'uzbl/') -DATA_DIR = join(xdghome('DATA', '.local/share/'), 'uzbl/') -CONFIG_DIR = join(xdghome('CONFIG', '.config/'), 'uzbl/') - -# Ensure data paths exist. -for path in [CACHE_DIR, DATA_DIR, CONFIG_DIR]: - if not os.path.exists(path): - os.makedirs(path) - -# Default config -config = { - - # Default cookie jar, whitelist, and daemon socket locations. - 'cookie_jar': join(DATA_DIR, 'cookies.txt'), - 'cookie_whitelist': join(CONFIG_DIR, 'cookie_whitelist'), - 'cookie_socket': join(CACHE_DIR, 'cookie_daemon_socket'), - - # Don't use a cookie whitelist policy by default. - 'use_whitelist': False, - - # Time out after x seconds of inactivity (set to 0 for never time out). - # WARNING: Do not use this option if you are manually launching the daemon. - 'daemon_timeout': 0, - - # Daemonise by default. - 'daemon_mode': True, - - # Optionally print helpful debugging messages to the terminal. - 'verbose': False, - -} # End of config dictionary. - - -# ============================================================================ -# ::: End of configuration section ::::::::::::::::::::::::::::::::::::::::::: -# ============================================================================ - - -_SCRIPTNAME = os.path.basename(sys.argv[0]) -def echo(msg): - '''Prints only if the verbose flag has been set.''' - - if config['verbose']: - sys.stderr.write("%s: %s\n" % (_SCRIPTNAME, msg)) - - -def error(msg): - '''Prints error message and exits.''' - - sys.stderr.write("%s: error: %s\n" % (_SCRIPTNAME, msg)) - sys.exit(1) - - -def mkbasedir(filepath): - '''Create the base directories of the file in the file-path if the dirs - don't exist.''' - - dirname = os.path.dirname(filepath) - if not os.path.exists(dirname): - echo("creating dirs: %r" % dirname) - os.makedirs(dirname) - - -def daemon_running(cookie_socket): - '''Check if another process (hopefully a cookie_daemon.py) is listening - on the cookie daemon socket. If another process is found to be - listening on the socket exit the daemon immediately and leave the - socket alone. If the connect fails assume the socket has been abandoned - and delete it (to be re-created in the create socket function).''' - - if not os.path.exists(cookie_socket): - return False - - if os.path.isfile(cookie_socket): - raise Exception("regular file at %r is not a socket" % cookie_socket) - - - if os.path.isdir(cookie_socket): - raise Exception("directory at %r is not a socket" % cookie_socket) - - try: - sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) - sock.connect(cookie_socket) - sock.close() - echo("detected daemon listening on %r" % cookie_socket) - return True - - except socket.error: - # Failed to connect to cookie_socket so assume it has been - # abandoned by another cookie daemon process. - if os.path.exists(cookie_socket): - echo("deleting abandoned socket at %r" % cookie_socket) - os.remove(cookie_socket) - - return False - - -def send_command(cookie_socket, cmd): - '''Send a command to a running cookie daemon.''' - - if not daemon_running(cookie_socket): - return False - - try: - sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) - sock.connect(cookie_socket) - sock.send(cmd) - sock.close() - echo("sent command %r to %r" % (cmd, cookie_socket)) - return True - - except socket.error: - print_exc() - error("failed to send message %r to %r" % (cmd, cookie_socket)) - return False - - -def kill_daemon(cookie_socket): - '''Send the "EXIT" command to running cookie_daemon.''' - - if send_command(cookie_socket, "EXIT"): - # Now ensure the cookie_socket is cleaned up. - start = time.time() - while os.path.exists(cookie_socket): - time.sleep(0.1) - if (time.time() - start) > 5: - error("force deleting socket %r" % cookie_socket) - os.remove(cookie_socket) - return - - echo("stopped daemon listening on %r"% cookie_socket) - - else: - if os.path.exists(cookie_socket): - os.remove(cookie_socket) - echo("removed abandoned/broken socket %r" % cookie_socket) - - -def daemonize(): - '''Daemonize the process using the Stevens' double-fork magic.''' - - try: - if os.fork(): - os._exit(0) - - except OSError: - print_exc() - sys.stderr.write("fork #1 failed") - sys.exit(1) - - os.chdir('/') - os.setsid() - os.umask(0) - - try: - if os.fork(): - os._exit(0) - - except OSError: - print_exc() - sys.stderr.write("fork #2 failed") - sys.exit(1) - - if sys.stdout.isatty(): - sys.stdout.flush() - sys.stderr.flush() - - devnull = '/dev/null' - stdin = file(devnull, 'r') - stdout = file(devnull, 'a+') - stderr = file(devnull, 'a+', 0) - - os.dup2(stdin.fileno(), sys.stdin.fileno()) - os.dup2(stdout.fileno(), sys.stdout.fileno()) - os.dup2(stderr.fileno(), sys.stderr.fileno()) - - -class CookieMonster: - '''The uzbl cookie daemon class.''' - - def __init__(self): - '''Initialise class variables.''' - - self.server_socket = None - self.jar = None - self.last_request = time.time() - self._running = False - - - def run(self): - '''Start the daemon.''' - - # The check healthy function will exit if another daemon is detected - # listening on the cookie socket and remove the abandoned socket if - # there isnt. - if os.path.exists(config['cookie_socket']): - if daemon_running(config['cookie_socket']): - sys.exit(1) - - # Create cookie daemon socket. - self.create_socket() - - # Daemonize process. - if config['daemon_mode']: - echo("entering daemon mode") - daemonize() - - # Register a function to cleanup on exit. - atexit.register(self.quit) - - # Make SIGTERM act orderly. - signal(SIGTERM, lambda signum, stack_frame: sys.exit(1)) - - # Create cookie jar object from file. - self.open_cookie_jar() - - # Create a way to exit nested loops by setting a running flag. - self._running = True - - while self._running: - try: - # Enter main listen loop. - self.listen() - - except KeyboardInterrupt: - self._running = False - print - - except socket.error: - print_exc() - - except: - # Clean up - self.del_socket() - - # Raise exception - raise - - # Always delete the socket before calling create again. - self.del_socket() - # Create cookie daemon socket. - self.create_socket() - - - def load_whitelist(self): - '''Load the cookie jar whitelist policy.''' - - cookie_whitelist = config['cookie_whitelist'] - - if cookie_whitelist: - mkbasedir(cookie_whitelist) - - # Create cookie whitelist file if it does not exist. - if not os.path.exists(cookie_whitelist): - open(cookie_whitelist, 'w').close() - - # Read cookie whitelist file into list. - file = open(cookie_whitelist,'r') - domain_list = [line.rstrip('\n') for line in file] - file.close() - - # Define policy of allowed domains - policy = cookielib.DefaultCookiePolicy(allowed_domains=domain_list) - self.jar.set_policy(policy) - - # Save the last modified time of the whitelist. - self._whitelistmtime = os.stat(cookie_whitelist).st_mtime - - - def open_cookie_jar(self): - '''Open the cookie jar.''' - - cookie_jar = config['cookie_jar'] - cookie_whitelist = config['cookie_whitelist'] - - if cookie_jar: - mkbasedir(cookie_jar) - - # Create cookie jar object from file. - self.jar = cookielib.MozillaCookieJar(cookie_jar) - - # Load cookie whitelist policy. - if config['use_whitelist']: - self.load_whitelist() - - if cookie_jar: - try: - # Attempt to load cookies from the cookie jar. - self.jar.load(ignore_discard=True) - - # Ensure restrictive permissions are set on the cookie jar - # to prevent other users on the system from hi-jacking your - # authenticated sessions simply by copying your cookie jar. - os.chmod(cookie_jar, 0600) - - except: - pass - - - def reload_whitelist(self): - '''Reload the cookie whitelist.''' - - cookie_whitelist = config['cookie_whitelist'] - if os.path.exists(cookie_whitelist): - echo("reloading whitelist %r" % cookie_whitelist) - self.open_cookie_jar() - - - def create_socket(self): - '''Create AF_UNIX socket for communication with uzbl instances.''' - - cookie_socket = config['cookie_socket'] - mkbasedir(cookie_socket) - - self.server_socket = socket.socket(socket.AF_UNIX, - socket.SOCK_SEQPACKET) - - self.server_socket.bind(cookie_socket) - - # Set restrictive permissions on the cookie socket to prevent other - # users on the system from data-mining your cookies. - os.chmod(cookie_socket, 0600) - - - def listen(self): - '''Listen for incoming cookie PUT and GET requests.''' - - daemon_timeout = config['daemon_timeout'] - echo("listening on %r" % config['cookie_socket']) - - connections = [] - - while self._running: - # This line tells the socket how many pending incoming connections - # to enqueue at once. Raising this number may or may not increase - # performance. - self.server_socket.listen(1) - - r, w, x = select.select([self.server_socket]+connections, [], [], 1) - - for socket in r: - if self.server_socket == socket: - client_socket, _ = socket.accept() - connections.append(client_socket) - else: - if not self.handle_request(socket): - # connection was closed, forget about the client socket - connections.remove(socket) - - self.last_request = time.time() - - if daemon_timeout: - # Checks if the daemon has been idling for too long. - idle = time.time() - self.last_request - if idle > daemon_timeout: - self._running = False - - - def handle_request(self, client_socket): - '''Connection made, now to serve a cookie PUT or GET request.''' - - # Receive cookie request from client. - data = client_socket.recv(8192) - if not data: - return False - - # Cookie argument list in packet is null separated. - argv = data.split("\0") - action = argv[0].upper().strip() - - # Catch the EXIT command sent to kill running daemons. - if action == "EXIT": - self._running = False - return False - - # Catch whitelist RELOAD command. - elif action == "RELOAD": - self.reload_whitelist() - return True - - # Return if command unknown. - elif action not in ['GET', 'PUT']: - error("unknown command %r." % argv) - return True - - # Determine whether or not to print cookie data to terminal. - print_cookie = (config['verbose'] and not config['daemon_mode']) - if print_cookie: - print ' '.join(argv[:4]) - - uri = urllib2.urlparse.ParseResult( - scheme=argv[1], - netloc=argv[2], - path=argv[3], - params='', - query='', - fragment='').geturl() - - req = urllib2.Request(uri) - - if action == "GET": - self.jar._policy._now = self._now = int(time.time()) - cookies = self.jar._cookies_for_request(req) - attrs = self.jar._cookie_attrs(cookies) - if attrs: - cookie = "; ".join(attrs) - client_socket.send(cookie) - if print_cookie: - print cookie - else: - client_socket.send("\0") - - elif action == "PUT": - cookie = argv[4] if len(argv) > 3 else None - if print_cookie: - print cookie - - self.put_cookie(req, cookie) - client_socket.send("\0") - - if print_cookie: - print - - return True - - - def put_cookie(self, req, cookie=None): - '''Put a cookie in the cookie jar.''' - - hdr = urllib2.httplib.HTTPMessage(\ - StringIO.StringIO('Set-Cookie: %s' % cookie)) - res = urllib2.addinfourl(StringIO.StringIO(), hdr, - req.get_full_url()) - self.jar.extract_cookies(res, req) - if config['cookie_jar']: - self.jar.save(ignore_discard=True) - - - def del_socket(self): - '''Remove the cookie_socket file on exit. In a way the cookie_socket - is the daemons pid file equivalent.''' - - if self.server_socket: - try: - self.server_socket.close() - - except: - pass - - self.server_socket = None - - cookie_socket = config['cookie_socket'] - if os.path.exists(cookie_socket): - echo("deleting socket %r" % cookie_socket) - os.remove(cookie_socket) - - - def quit(self): - '''Called on exit to make sure all loose ends are tied up.''' - - self.del_socket() - sys.exit(0) - - -def main(): - '''Main function.''' - - # Define command line parameters. - usage = "usage: %prog [options] {start|stop|restart|reload}" - parser = OptionParser(usage=usage) - parser.add_option('-n', '--no-daemon', dest='no_daemon', - action='store_true', help="don't daemonise the process.") - - parser.add_option('-v', '--verbose', dest="verbose", - action='store_true', help="print verbose output.") - - parser.add_option('-t', '--daemon-timeout', dest='daemon_timeout', - action="store", metavar="SECONDS", help="shutdown the daemon after x "\ - "seconds inactivity. WARNING: Do not use this when launching the "\ - "cookie daemon manually.") - - parser.add_option('-s', '--cookie-socket', dest="cookie_socket", - metavar="SOCKET", help="manually specify the socket location.") - - parser.add_option('-j', '--cookie-jar', dest='cookie_jar', - metavar="FILE", help="manually specify the cookie jar location.") - - parser.add_option('-m', '--memory', dest='memory', action='store_true', - help="store cookies in memory only - do not write to disk") - - parser.add_option('-u', '--use-whitelist', dest='usewhitelist', - action='store_true', help="use cookie whitelist policy") - - parser.add_option('-w', '--cookie-whitelist', dest='whitelist', - action='store', help="manually specify whitelist location", - metavar='FILE') - - # Parse the command line arguments. - (options, args) = parser.parse_args() - - expand = lambda p: os.path.realpath(os.path.expandvars(p)) - - initcommands = ['start', 'stop', 'restart', 'reload'] - for arg in args: - if arg not in initcommands: - error("unknown argument %r" % args[0]) - sys.exit(1) - - if len(args) > 1: - error("the daemon only accepts one {%s} action at a time." - % '|'.join(initcommands)) - sys.exit(1) - - if len(args): - action = args[0] - - else: - action = "start" - - if options.no_daemon: - config['daemon_mode'] = False - - if options.cookie_socket: - config['cookie_socket'] = expand(options.cookie_socket) - - if options.cookie_jar: - config['cookie_jar'] = expand(options.cookie_jar) - - if options.memory: - config['cookie_jar'] = None - - if options.whitelist: - config['cookie_whitelist'] = expand(options.whitelist) - - if options.whitelist or options.usewhitelist: - config['use_whitelist'] = True - - if options.daemon_timeout: - try: - config['daemon_timeout'] = int(options.daemon_timeout) - - except ValueError: - error("expected int argument for -t, --daemon-timeout") - - # Expand $VAR's in config keys that relate to paths. - for key in ['cookie_socket', 'cookie_jar', 'cookie_whitelist']: - if config[key]: - config[key] = os.path.expandvars(config[key]) - - if options.verbose: - config['verbose'] = True - import pprint - sys.stderr.write("%s\n" % pprint.pformat(config)) - - # It would be better if we didn't need to start this python process just - # to send a command to the socket, but unfortunately socat doesn't seem - # to support SEQPACKET. - if action == "reload": - send_command(config['cookie_socket'], "RELOAD") - - if action in ['stop', 'restart']: - kill_daemon(config['cookie_socket']) - - if action in ['start', 'restart']: - CookieMonster().run() - - -if __name__ == "__main__": - main() diff --git a/examples/uzbl-cookie-manager.c b/examples/uzbl-cookie-manager.c deleted file mode 100644 index 70addf3..0000000 --- a/examples/uzbl-cookie-manager.c +++ /dev/null @@ -1,381 +0,0 @@ -#define _POSIX_SOURCE - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "../src/util.h" - -extern const XDG_Var XDG[]; - -int verbose = 0; - -#define SOCK_BACKLOG 10 -#define MAX_COOKIE_LENGTH 4096 - -char cookie_buffer[MAX_COOKIE_LENGTH]; - -int setup_socket(const char *cookied_socket_path) { - /* delete the cookie socket if it was left behind on a previous run */ - unlink(cookied_socket_path); - - int socket_fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); - - if(socket_fd < 0) { - fprintf(stderr, "socket failed (%s)\n", strerror(errno)); - return -1; - } - - struct sockaddr_un sa; - sa.sun_family = AF_UNIX; - strcpy(sa.sun_path, cookied_socket_path); - - if(bind(socket_fd, (struct sockaddr*)&sa, sizeof(sa)) < 0) { - fprintf(stderr, "bind failed (%s)\n", strerror(errno)); - return -1; - } - - if(listen(socket_fd, SOCK_BACKLOG) < 0) { - fprintf(stderr, "listen failed (%s)\n", strerror(errno)); - return -1; - } - - return socket_fd; -} - -const char *whitelist_path = NULL; -GPtrArray *whitelisted_hosts = NULL; -time_t whitelist_update_time = 0; - -void whitelist_line_cb(const gchar* line, void *user_data) { - (void) user_data; - - gchar *norm_host; - - const gchar *p = line; - while(isspace(*p)) - p++; - - if(p[0] == '#' || !p[0]) /* ignore comments and blank lines */ - return; - - if(p[0] == '.') - norm_host = g_strdup(p); - else - norm_host = g_strconcat(".", p, NULL); - - g_ptr_array_add(whitelisted_hosts, g_strchomp(norm_host)); -} - -gboolean load_whitelist(const char *whitelist_path) { - if(!file_exists(whitelist_path)) - return FALSE; - - /* check if the whitelist file was updated */ - struct stat f; - if(stat(whitelist_path, &f) < 0) - return FALSE; - - if(whitelisted_hosts == NULL) - whitelisted_hosts = g_ptr_array_new(); - - if(f.st_mtime > whitelist_update_time) { - /* the file was updated, reload the whitelist */ - if(verbose) puts("reloading whitelist"); - while(whitelisted_hosts->len > 0) { - g_free(g_ptr_array_index(whitelisted_hosts, 0)); - g_ptr_array_remove_index_fast(whitelisted_hosts, 0); - } - for_each_line_in_file(whitelist_path, whitelist_line_cb, NULL); - whitelist_update_time = f.st_mtime; - } - - return TRUE; -} - -gboolean should_save_cookie(const char *host) { - if(!load_whitelist(whitelist_path)) - return TRUE; /* some error with the file, assume no whitelist */ - - /* we normalize the hostname so it has a . in front like the whitelist entries */ - gchar *test_host = (host[0] == '.') ? g_strdup(host) : g_strconcat(".", host, NULL); - int hl = strlen(test_host); - - /* test against each entry in the whitelist */ - gboolean result = FALSE; - guint i; - for(i = 0; i < whitelisted_hosts->len; i++) { - /* a match means the host ends with (or is equal to) the whitelist entry */ - const gchar *entry = g_ptr_array_index(whitelisted_hosts, i); - int el = strlen(entry); - result = (el <= hl) && !strcmp(test_host + (hl - el), entry); - - if(result) - break; - } - - g_free(test_host); - - return result; -} - -void handle_request(SoupCookieJar *j, const char *buff, int len, int fd) { - const char *command = buff; - - const char *scheme = command + strlen(command) + 1; - if((scheme - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - const char *host = scheme + strlen(scheme) + 1; - if((host - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - const char *path = host + strlen(host) + 1; - if((path - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - /* glue the parts back together into a SoupURI */ - char *u = g_strconcat(scheme, "://", host, path, NULL); - if(verbose) printf("%s %s\n", command, u); - SoupURI *uri = soup_uri_new(u); - g_free(u); - - if(!strcmp(command, "GET")) { - char *result = soup_cookie_jar_get_cookies(j, uri, TRUE); - if(result) { - if(verbose) puts(result); - if(write(fd, result, strlen(result)+1) < 0) - fprintf(stderr, "write failed (%s)", strerror(errno)); - - g_free(result); - } else { - if(verbose) puts("-"); - if(write(fd, "", 1) < 0) - fprintf(stderr, "write failed (%s)", strerror(errno)); - } - } else if(!strcmp(command, "PUT")) { - const char *name_and_val = path + strlen(path) + 1; - if((name_and_val - buff) > len) { - fprintf(stderr, "got malformed or partial request\n"); - return; - } - - if(verbose) puts(name_and_val); - - if(should_save_cookie(host)) { - char *eql = strchr(name_and_val, '='); - eql[0] = 0; - - const char *name = name_and_val; - const char *value = eql + 1; - - SoupCookie *cookie = soup_cookie_new(name, value, host, path, SOUP_COOKIE_MAX_AGE_ONE_YEAR); - - soup_cookie_jar_add_cookie(j, cookie); - } else if(verbose) - puts("no, blacklisted."); - - if(write(fd, "", 1) < 0) - fprintf(stderr, "write failed (%s)", strerror(errno)); - } - - soup_uri_free(uri); -} - -void -wait_for_things_to_happen_and_then_do_things(SoupCookieJar* j, int cookie_socket) { - GArray *connections = g_array_new (FALSE, FALSE, sizeof (int)); - - while(1) { - unsigned int i; - int r; - fd_set fs; - - int maxfd = cookie_socket; - FD_ZERO(&fs); - FD_SET(maxfd, &fs); - - for(i = 0; i < connections->len; i++) { - int fd = g_array_index(connections, int, i); - if(fd > maxfd) maxfd = fd; - FD_SET(fd, &fs); - } - - r = select(maxfd+1, &fs, NULL, NULL, NULL); - if(r < 0) { - fprintf(stderr, "select failed (%s)\n", strerror(errno)); - continue; - } - - if(FD_ISSET(cookie_socket, &fs)) { - /* handle new connection */ - int fd = accept(cookie_socket, NULL, NULL); - g_array_append_val(connections, fd); - if(verbose) puts("got connection."); - } - - for(i = 0; i < connections->len; i++) { - /* handle activity on a connection */ - int fd = g_array_index(connections, int, i); - if(FD_ISSET(fd, &fs)) { - r = read(fd, cookie_buffer, MAX_COOKIE_LENGTH); - if(r < 0) { - fprintf(stderr, "read failed (%s)\n", strerror(errno)); - continue; - } else if(r == 0) { - if(verbose) puts("client hung up."); - g_array_remove_index(connections, i); - i--; /* other elements in the array are moved down to fill the gap */ - continue; - } - cookie_buffer[r] = 0; - - handle_request(j, cookie_buffer, r, fd); - } - } - } -} - -void usage(const char *progname) { - printf("%s [-s socket-path] [-f cookies.txt] [-w whitelist-file] [-n] [-v]\n", progname); - puts("\t-n\tdon't daemonise the process"); - puts("\t-v\tbe verbose"); -} - -void daemonise() { - int r = fork(); - - if(r < 0) { - fprintf(stderr, "fork failed (%s)", strerror(errno)); - exit(1); - } else if (r > 0) { - /* this is the parent, which has done its job */ - exit(0); - } - - if(setsid() < 0) { - fprintf(stderr, "setsid failed (%s)", strerror(errno)); - exit(1); - } -} - -const char *pid_file_path = NULL; -const char *cookied_socket_path = NULL; - -void cleanup_after_signal(int signal) { - (void) signal; - unlink(pid_file_path); - unlink(cookied_socket_path); - exit(0); -} - -int main(int argc, char *argv[]) { - int i; - - const char *cookies_txt_path = NULL; - gboolean foreground = FALSE; - - for(i = 1; i < argc && argv[i][0] == '-'; i++) { - switch(argv[i][1]) { - case 's': - cookied_socket_path = argv[++i]; - break; - case 'f': - cookies_txt_path = argv[++i]; - break; - case 'w': - whitelist_path = argv[++i]; - break; - case 'n': - foreground = TRUE; - break; - case 'v': - verbose = 1; - break; - default: - usage(argv[0]); - return 1; - } - } - - if(!foreground) - daemonise(); - - if(!cookies_txt_path) - cookies_txt_path = g_strconcat(get_xdg_var(XDG[1]), "/uzbl/cookies.txt", NULL); - - if(!cookied_socket_path) - cookied_socket_path = g_strconcat(get_xdg_var(XDG[2]), "/uzbl/cookie_daemon_socket", NULL); - - if(!whitelist_path) - whitelist_path = g_strconcat(get_xdg_var(XDG[0]), "/uzbl/cookie_whitelist", NULL); - - /* write out and lock the pid file. - * this ensures that only one uzbl-cookie-manager is running per-socket. - * (we should probably also lock the cookies.txt to prevent accidents...) */ - pid_file_path = g_strconcat(cookied_socket_path, ".pid", NULL); - int lockfd = open(pid_file_path, O_RDWR|O_CREAT, 0600); - if(lockfd < 0) { - fprintf(stderr, "couldn't open pid file %s (%s)\n", pid_file_path, strerror(errno)); - return 1; - } - - if(flock(lockfd, LOCK_EX|LOCK_NB) < 0) { - fprintf(stderr, "couldn't lock pid file %s (%s)\n", pid_file_path, strerror(errno)); - fprintf(stderr, "uzbl-cookie-manager is probably already running\n"); - return 1; - } - - gchar* pids = g_strdup_printf("%d\n", getpid()); - write(lockfd, pids, strlen(pids)); - g_free(pids); - - struct sigaction sa; - sa.sa_handler = cleanup_after_signal; - if(sigaction(SIGINT, &sa, NULL) || sigaction(SIGTERM, &sa, NULL)) { - fprintf(stderr, "sigaction failed (%s)\n", strerror(errno)); - return 1; - } - - if(!foreground) { - /* close STDIO */ - close(0); - close(1); - close(2); - } - - g_type_init(); - - SoupCookieJar *j = soup_cookie_jar_text_new(cookies_txt_path, FALSE); - - int cookie_socket = setup_socket(cookied_socket_path); - if(cookie_socket < 0) - return 1; - - wait_for_things_to_happen_and_then_do_things(j, cookie_socket); - - return 0; -} diff --git a/src/uzbl-browser b/src/uzbl-browser index faa2829..81645ca 100755 --- a/src/uzbl-browser +++ b/src/uzbl-browser @@ -64,13 +64,6 @@ then export UZBL_UTIL_DIR fi -# uzbl-cookie-manager will exit if another instance is already running. -# we could also check if its pid file exists to avoid having to spawn it. -#if [ ! -f "$XDG_CACHE_HOME"/uzbl/cookie_daemon_socket.pid ] -#then -# ${UZBL_COOKIE_DAEMON:-uzbl-cookie-manager} -#fi - # uzbl-event-manager will exit if one is already running. # we could also check if its pid file exists to avoid having to spawn it. DAEMON_SOCKET="$XDG_CACHE_HOME"/uzbl/event_daemon -- cgit v1.2.3 From f6bd9e08bf16165f1ae2a7c98255fd89709a72a9 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 27 Dec 2010 21:40:22 -0700 Subject: remove talk_to_socket and all its associated bits --- README | 5 - docs/README.cookies | 63 ---------- extras/vim/syntax/uzbl.vim | 2 +- src/callbacks.c | 10 -- src/callbacks.h | 3 - src/cookie-jar.c | 286 ++------------------------------------------- src/cookie-jar.h | 12 -- src/uzbl-core.c | 5 +- src/uzbl-core.h | 1 - 9 files changed, 12 insertions(+), 375 deletions(-) delete mode 100644 docs/README.cookies diff --git a/README b/README index 35492da..2c87290 100644 --- a/README +++ b/README @@ -183,11 +183,6 @@ The following commands are recognized: the end, so the argument numbers will be higher. * `sync_sh ` - Synchronous version of `sh`, See `sync_spawn`. -* `talk_to_socket ` - - Send a message to `` and wait for a response. `` are - concatenated and separated by ASCII NUL bytes. - - Expects the socket type to be `SOCK_SEQPACKET` (see `connect(2)`). - - Waits for 500ms for a response. * `exit` - Closes `uzbl`. * `search ` diff --git a/docs/README.cookies b/docs/README.cookies deleted file mode 100644 index 148603f..0000000 --- a/docs/README.cookies +++ /dev/null @@ -1,63 +0,0 @@ -# Cookies and Uzbl # - -The speed of cookie lookups is important, since a single page load can involve -dozens of HTTP requests, each of which needs a separate cookie lookup (since -another instance of uzbl may have obtained new cookies for a site). - -It is possible handle cookie lookup (and storage) using a `spawn_async` cookie -handler, but spawning new processes is inherently slow so a `talk_to_socket` -cookie daemon (like the default uzbl-cookie-manager) is recommended. - -## uzbl-cookie-manager ## - -uzbl-cookie-manager is a cookie daemon based on libsoup's SoupCookieJar. Cookies -are stored in a file in the Mozilla cookies.txt format (default location -$XDG_DATA_HOME/.local/share/cookies.txt). - -### uzbl-cookie-manager Whitelist ### - -If a whitelist file is present (default location -$XDG_CONFIG_HOME/uzbl/cookie_whitelist), then website attempts to set cookies -will be ignored unless the site's domain is present in the whitelist. - -The whitelist can contain comment lines beginning with `#`, and domain lines. A -domain line beginning with . will whitelist the given domain name and any -subdomain of it. Otherwise only exact matches of the domain are whitelisted. - -For instance, given this whitelist file: - - example.com - .uzbl.org - -uzbl-cookie-manager would accept cookies for example.com, uzbl.org and -www.uzbl.org, but ignore cookies set for www.example.com (and any other -domain that is not a subdomain of uzbl.org). - -## uzbl-cookie-daemon ## - -uzbl-cookie-daemon is a Python cookie daemon based on Python's cookielib. -Cookielib's lookup algorithm isn't very efficient for our needs, so -uzbl-cookie-daemon is noticeably slow. - -## Cookie Daemon Protocol ## - -When uzbl's `cookie_handler` variable is set to `talk_to_socket path`, uzbl -connects to the Unix domain socket located at `path`. uzbl will send a cookie -lookup request on this socket every time it makes an HTTP request. The format of -this lookup request is: - - GET\0scheme\0host\0path\0 - -where `\0` is the null character, `scheme` is the URL scheme (http or https), -`host` is the hostname from the URL and `path` is the requested path. The cookie -daemon should respond with the names and values of cookies that match the -request, in the format used by the `Cookie` header, terminated with a `\0`. - -When a website adds, deletes or changes a cookie, uzbl notifies the cookie -daemon with a request in the format: - - PUT\0scheme\0host\0path\0name=value\0 - -where `scheme`, `host` and `path` are (approximately) as above, and `name=value` -is the cookie name-value pair to store. The cookie daemon should respond by -writing `\0` to the socket. diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index b8572c9..bf7108c 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -30,7 +30,7 @@ setl iskeyword=!-~,192-255 syn keyword uzblKeyword back forward scroll reload reload_ign_cache stop syn keyword uzblKeyword zoom_in zoom_out toggle_zoom_type uri script -syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh talk_to_socket +syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh sync_spawn_exec syn keyword uzblKeyword exit search search_reverse search_clear dehilight set syn keyword uzblKeyword dump_config dump_config_as_events chain print event syn keyword uzblKeyword request menu_add menu_link_add menu_image_add diff --git a/src/callbacks.c b/src/callbacks.c index f09dd0d..f41ac74 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -983,13 +983,3 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { } } } - -void -cmd_set_cookie_handler() { - if(uzbl.behave.cookie_handler[0] == 0) { - g_free(uzbl.behave.cookie_handler); - uzbl.behave.cookie_handler = NULL; - } - - uzbl_cookie_jar_set_handler(uzbl.net.soup_cookie_jar, uzbl.behave.cookie_handler); -} diff --git a/src/callbacks.h b/src/callbacks.h index 40fa80d..2116dd4 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -213,6 +213,3 @@ scroll_vert_cb(GtkAdjustment *adjust, void *w); gboolean scroll_horiz_cb(GtkAdjustment *adjust, void *w); - -void -cmd_set_cookie_handler(); diff --git a/src/cookie-jar.c b/src/cookie-jar.c index 626e454..82a5269 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -1,51 +1,20 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include #include #include "cookie-jar.h" #include "uzbl-core.h" #include "events.h" -static void -uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data); - -G_DEFINE_TYPE_WITH_CODE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR, - G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, uzbl_cookie_jar_session_feature_init)) +G_DEFINE_TYPE (UzblCookieJar, soup_cookie_jar_socket, SOUP_TYPE_COOKIE_JAR) -static void request_started (SoupSessionFeature *feature, SoupSession *session, SoupMessage *msg, SoupSocket *socket); static void changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie); -static void setup_handler(UzblCookieJar *jar); - -static void connect_cookie_socket(UzblCookieJar *jar); -static void disconnect_cookie_socket(UzblCookieJar *jar); - -static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_len); - -static bool has_socket_handler(UzblCookieJar *jar) { - return jar->socket_path != NULL; -} - static void soup_cookie_jar_socket_init(UzblCookieJar *jar) { - jar->handler = NULL; - jar->socket_path = NULL; - jar->connection_fd = -1; - jar->in_get_callback = 0; jar->in_manual_add = 0; } static void finalize(GObject *object) { - disconnect_cookie_socket(UZBL_COOKIE_JAR(object)); G_OBJECT_CLASS(soup_cookie_jar_socket_parent_class)->finalize(object); } @@ -55,120 +24,30 @@ soup_cookie_jar_socket_class_init(UzblCookieJarClass *socket_class) { SOUP_COOKIE_JAR_CLASS(socket_class)->changed = changed; } -/* override SoupCookieJar's request_started handler */ -static void -uzbl_cookie_jar_session_feature_init(SoupSessionFeatureInterface *iface, gpointer user_data) { - (void) user_data; - iface->request_started = request_started; -} - UzblCookieJar *uzbl_cookie_jar_new() { return g_object_new(UZBL_TYPE_COOKIE_JAR, NULL); } -void -uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar* handler) { - jar->handler = handler; - setup_handler(jar); -} - -char *get_cookies(UzblCookieJar *jar, SoupURI *uri) { - gchar *result, *path; - GString *s = g_string_new ("GET"); - - path = uri->path[0] ? uri->path : "/"; - - if(has_socket_handler(jar)) { - g_string_append_c(s, 0); /* null-terminate the GET */ - g_string_append_len(s, uri->scheme, strlen(uri->scheme)+1); - g_string_append_len(s, uri->host, strlen(uri->host)+1 ); - g_string_append_len(s, path, strlen(path)+1 ); - - result = do_socket_request(jar, s->str, s->len); - /* try it again; older cookie daemons closed the connection after each request */ - if(result == NULL) - result = do_socket_request(jar, s->str, s->len); - } else { - g_string_append_printf(s, " '%s' '%s' '%s'", uri->scheme, uri->host, uri->path); - - run_handler(jar->handler, s->str); - result = g_strdup(uzbl.comm.sync_stdout); - } - g_string_free(s, TRUE); - return result; -} - -/* this is a duplicate of SoupCookieJar's request_started that uses our get_cookies instead */ -static void -request_started(SoupSessionFeature *feature, SoupSession *session, - SoupMessage *msg, SoupSocket *socket) { - (void) session; (void) socket; - gchar *cookies; - - UzblCookieJar *jar = UZBL_COOKIE_JAR (feature); - SoupURI *uri = soup_message_get_uri(msg); - gboolean add_to_internal_jar = false; - - if(jar->handler) { - cookies = get_cookies(jar, uri); - } else { - /* no handler is set, fall back to the internal soup cookie jar */ - cookies = soup_cookie_jar_get_cookies(SOUP_COOKIE_JAR(jar), soup_message_get_uri (msg), TRUE); - } - - if (cookies && cookies[0] != 0) { - const gchar *next_cookie_start = cookies; - - if (add_to_internal_jar) { - /* add the cookie data that we just obtained from the cookie handler - to the cookie jar so that javascript has access to them. - we set this flag so that we don't trigger the PUT handler. */ - jar->in_get_callback = true; - do { - SoupCookie *soup_cookie = soup_cookie_parse(next_cookie_start, uri); - if(soup_cookie) - soup_cookie_jar_add_cookie(SOUP_COOKIE_JAR(uzbl.net.soup_cookie_jar), soup_cookie); - next_cookie_start = strchr(next_cookie_start, ';'); - } while(next_cookie_start++ != NULL); - jar->in_get_callback = false; - } - - soup_message_headers_replace (msg->request_headers, "Cookie", cookies); - } else { - soup_message_headers_remove (msg->request_headers, "Cookie"); - } - - if(cookies) - g_free (cookies); -} - static void changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { - SoupCookie * cookie = new_cookie ? new_cookie : old_cookie; + SoupCookie *cookie = new_cookie ? new_cookie : old_cookie; UzblCookieJar *uzbl_jar = UZBL_COOKIE_JAR(jar); - /* when Uzbl begins an HTTP request, it GETs cookies from the handler - and then adds them to the cookie jar so that javascript can access - these cookies. this causes a 'changed' callback, which we don't want - to do anything, so we just return. - - (if SoupCookieJar let us override soup_cookie_jar_get_cookies we - wouldn't have to do this.) */ - if(uzbl_jar->in_get_callback) - return; - - gchar *scheme = cookie->secure ? "https" : "http"; - - /* send a ADD or DELETE -_COOKIE event depending on what have changed */ + /* send a ADD or DELETE -_COOKIE event depending on what has changed. these + * events aren't sent when a cookie changes due to an add/delete_cookie + * command because otherwise a loop would occur when a cookie change is + * propagated to other uzbl instances using add/delete_cookie. */ if(!uzbl_jar->in_manual_add) { + gchar *scheme = cookie->secure ? "https" : "http"; + gchar *expires = NULL; if(cookie->expires) expires = g_strdup_printf ("%d", soup_date_to_time_t (cookie->expires)); gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'", cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:""); - if(new_cookie) + if(new_cookie) send_event(ADD_COOKIE, eventstr, NULL); else send_event(DELETE_COOKIE, eventstr, NULL); @@ -176,151 +55,4 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { if(expires) g_free(expires); } - - /* the cookie daemon is only interested in new cookies and changed - ones, it can take care of deleting expired cookies on its own. */ - if(!new_cookie) - return; - - GString *s = g_string_new ("PUT"); - - if(has_socket_handler(uzbl_jar)) { - g_string_append_c(s, 0); /* null-terminate the PUT */ - g_string_append_len(s, scheme, strlen(scheme)+1); - g_string_append_len(s, new_cookie->domain, strlen(new_cookie->domain)+1 ); - g_string_append_len(s, new_cookie->path, strlen(new_cookie->path)+1 ); - g_string_append_printf(s, "%s=%s", new_cookie->name, new_cookie->value); - - gchar *result = do_socket_request(uzbl_jar, s->str, s->len+1); - /* try it again; older cookie daemons closed the connection after each request */ - if(!result) - result = do_socket_request(uzbl_jar, s->str, s->len+1); - - g_free(result); - } else { - g_string_append_printf(s, " '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value); - - run_handler(uzbl_jar->handler, s->str); - } - - g_string_free(s, TRUE); -} - -static void -setup_handler(UzblCookieJar *jar) { - if(jar->handler && strncmp(jar->handler, "talk_to_socket", strlen("talk_to_socket")) == 0) { - /* extract the socket path from the handler. */ - jar->socket_path = jar->handler + strlen("talk_to_socket"); - while(isspace(*jar->socket_path)) - jar->socket_path++; - if(*jar->socket_path == 0) - return; /* there was no path specified. */ - disconnect_cookie_socket(jar); - connect_cookie_socket(jar); - } else { - jar->socket_path = NULL; - } -} - -static void -connect_cookie_socket(UzblCookieJar *jar) { - struct sockaddr_un sa; - int fd; - - g_strlcpy(sa.sun_path, jar->socket_path, sizeof(sa.sun_path)); - sa.sun_family = AF_UNIX; - - /* create socket file descriptor and connect it to path */ - fd = socket(AF_UNIX, SOCK_SEQPACKET, 0); - if(fd == -1) { - g_printerr("connect_cookie_socket: creating socket failed (%s)\n", strerror(errno)); - return; - } - - if(connect(fd, (struct sockaddr*)&sa, sizeof(sa))) { - g_printerr("connect_cookie_socket: connect failed (%s)\n", strerror(errno)); - close(fd); - return; - } - - /* successful connection! */ - jar->connection_fd = fd; -} - -static void -disconnect_cookie_socket(UzblCookieJar *jar) { - if(jar->connection_fd > 0) { - close(jar->connection_fd); - jar->connection_fd = -1; - } -} - -static gchar *do_socket_request(UzblCookieJar *jar, gchar *request, int request_length) { - int len; - ssize_t ret; - struct pollfd pfd; - gchar *result = NULL; - - if(jar->connection_fd < 0) - connect_cookie_socket(jar); /* connection was lost, reconnect */ - - /* write request */ - ret = write(jar->connection_fd, request, request_length); - if(ret == -1) { - g_printerr("talk_to_socket: write failed (%s)\n", strerror(errno)); - disconnect_cookie_socket(jar); - return NULL; - } - - /* wait for a response, with a 500ms timeout */ - pfd.fd = jar->connection_fd; - pfd.events = POLLIN; - while(1) { - ret = poll(&pfd, 1, 500); - if(ret == 1) break; - if(ret == 0) errno = ETIMEDOUT; - if(errno == EINTR) continue; - g_printerr("talk_to_socket: poll failed while waiting for input (%s)\n", - strerror(errno)); - if(errno != ETIMEDOUT) - disconnect_cookie_socket(jar); - return NULL; - } - - /* get length of response */ - if(ioctl(jar->connection_fd, FIONREAD, &len) == -1) { - g_printerr("talk_to_socket: cannot find daemon response length, " - "ioctl failed (%s)\n", strerror(errno)); - disconnect_cookie_socket(jar); - return NULL; - } - - /* there was an empty response. */ - if(len == 0) - return g_strdup(""); - - /* there is a response, read it */ - result = g_malloc(len + 1); - if(!result) { - g_printerr("talk_to_socket: failed to allocate %d bytes\n", len); - return NULL; - } - result[len] = 0; /* ensure result is null terminated */ - - gchar *p = result; - while(len > 0) { - ret = read(jar->connection_fd, p, len); - if(ret == -1) { - g_printerr("talk_to_socket: failed to read from socket (%s)\n", - strerror(errno)); - disconnect_cookie_socket(jar); - g_free(result); - return NULL; - } else { - len -= ret; - p += ret; - } - } - - return result; } diff --git a/src/cookie-jar.h b/src/cookie-jar.h index f3e3733..05f4a6f 100644 --- a/src/cookie-jar.h +++ b/src/cookie-jar.h @@ -10,12 +10,6 @@ typedef struct { SoupCookieJar parent; - const gchar *handler; - - const gchar *socket_path; - int connection_fd; - - gboolean in_get_callback; gboolean in_manual_add; } UzblCookieJar; @@ -25,10 +19,4 @@ typedef struct { UzblCookieJar *uzbl_cookie_jar_new(); -void -uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar *handler); - -char -*get_cookies(UzblCookieJar *jar, SoupURI *uri); - #endif diff --git a/src/uzbl-core.c b/src/uzbl-core.c index fc21978..66842a9 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -90,7 +90,6 @@ const struct var_name_to_ptr_t { { "title_format_short", PTR_V_STR(uzbl.behave.title_format_short, 1, NULL)}, { "icon", PTR_V_STR(uzbl.gui.icon, 1, set_icon)}, { "forward_keys", PTR_V_INT(uzbl.behave.forward_keys, 1, NULL)}, - { "cookie_handler", PTR_V_STR(uzbl.behave.cookie_handler, 1, cmd_set_cookie_handler)}, { "authentication_handler", PTR_V_STR(uzbl.behave.authentication_handler, 1, set_authentication_handler)}, { "scheme_handler", PTR_V_STR(uzbl.behave.scheme_handler, 1, NULL)}, { "download_handler", PTR_V_STR(uzbl.behave.download_handler, 1, NULL)}, @@ -584,10 +583,10 @@ struct {const char *key; CommandInfo value;} cmdlist[] = { "script", {run_external_js, 0} }, { "toggle_status", {toggle_status_cb, 0} }, { "spawn", {spawn_async, 0} }, - { "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler + { "sync_spawn", {spawn_sync, 0} }, { "sync_spawn_exec", {spawn_sync_exec, 0} }, // needed for load_cookies.sh :( { "sh", {spawn_sh_async, 0} }, - { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler + { "sync_sh", {spawn_sh_sync, 0} }, { "exit", {close_uzbl, 0} }, { "search", {search_forward_text, TRUE} }, { "search_reverse", {search_reverse_text, TRUE} }, diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 98ae342..14f03a6 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -124,7 +124,6 @@ typedef struct { gchar* status_background; gchar* fifo_dir; gchar* socket_dir; - gchar* cookie_handler; gchar* authentication_handler; gchar* default_font_family; gchar* monospace_font_family; -- cgit v1.2.3 From 113853220d5d99720c448c76474c91fc283ea4e5 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Wed, 29 Dec 2010 16:56:33 -0700 Subject: fix a null pointer dereference in create_stdin (found with cppcheck) --- src/uzbl-core.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 34cf364..039c520 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1687,21 +1687,16 @@ control_stdin(GIOChannel *gio, GIOCondition condition) { void create_stdin () { - GIOChannel *chan = NULL; - GError *error = NULL; - - chan = g_io_channel_unix_new(fileno(stdin)); + GIOChannel *chan = g_io_channel_unix_new(fileno(stdin)); if (chan) { if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) { - g_error ("Stdin: could not add watch\n"); - } else { - if (uzbl.state.verbose) - printf ("Stdin: watch added successfully\n"); + g_error ("create_stdin: could not add watch\n"); + } else if (uzbl.state.verbose) { + printf ("create_stdin: watch added successfully\n"); } } else { - g_error ("Stdin: Error while opening: %s\n", error->message); + g_error ("create_stdin: error while opening stdin\n"); } - if (error) g_error_free (error); } gboolean -- cgit v1.2.3 From 15c83d8a85a150f46e80f7fc97041f10a43a96df Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 1 Jan 2011 03:01:48 +0100 Subject: malformed cookie rows pass through delete --- examples/data/plugins/cookies.py | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index c9fe2c3..9eccace 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -38,24 +38,38 @@ class TextStore(object): self.filename = filename def as_event(self, cookie): + """Convert cookie.txt row to uzbls cookie event format""" + scheme = { + 'TRUE' : 'https', + 'FALSE' : 'http' + } if cookie[0].startswith("#HttpOnly_"): domain = cookie[0][len("#HttpOnly_"):] elif cookie[0].startswith('#'): return None else: domain = cookie[0] - return (domain, - cookie[2], - cookie[5], - cookie[6], - 'https' if cookie[3] == 'TRUE' else 'http', - cookie[4]) + try: + return (domain, + cookie[2], + cookie[5], + cookie[6], + scheme[cookie[3]], + cookie[4]) + except (KeyError,IndexError): + # Let malformed rows pass through like comments + return None def as_file(self, cookie): + """Convert cookie event to cookie.txt row""" + secure = { + 'https' : 'TRUE', + 'http' : 'FALSE' + } return (cookie[0], 'TRUE' if cookie[0].startswith('.') else 'FALSE', cookie[1], - 'TRUE' if cookie[4] == 'https' else 'FALSE', + secure[cookie[4]], cookie[5], cookie[2], cookie[3]) -- cgit v1.2.3 From 08b45348831fadadeaac4cefb03eb11538c7aa0c Mon Sep 17 00:00:00 2001 From: keis Date: Tue, 11 Jan 2011 12:51:00 +0100 Subject: fix bug in history search disable keycmd set in search as this will not work from stacked bindings --- examples/config/config | 1 + examples/data/plugins/history.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/config/config b/examples/config/config index 7b9fba2..ddeca7b 100644 --- a/examples/config/config +++ b/examples/config/config @@ -185,6 +185,7 @@ set ebind = @mode_bind global,-insert @ebind = event HISTORY_PREV @ebind = event HISTORY_NEXT +@ebind r_ = event HISTORY_SEARCH %s # Keycmd injection/append examples. #@ebind su = event INJECT_KEYCMD \@uri #@ebind st = event INJECT_KEYCMD \@title diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 886cbe0..78a94ce 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -57,7 +57,7 @@ class History(object): def search(self, key): self.search_key = key - return self.prev() + self.cursor = None def add(self, cmd): if self._temporary: @@ -106,7 +106,7 @@ def history_next(uzbl, _x): uzbl.logger.debug('NEXT %s' % uzbl.history) def history_search(uzbl, key): - uzbl.set_keycmd(history.search(key)) + uzbl.history.search(key) uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history)) end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') -- cgit v1.2.3 -- cgit v1.2.3 From 1bb84ff92e4ed2e7594a8311ec95428a4a0600cc Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 12:11:09 -0700 Subject: simplify parse_cmd_line --- src/uzbl-core.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 147a9ae..8f9ff88 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1467,23 +1467,14 @@ set_var_value(const gchar *name, gchar *val) { void parse_cmd_line(const char *ctl_line, GString *result) { - size_t len=0; - gchar *ctlstrip = NULL; gchar *exp_line = NULL; - gchar *work_string = NULL; + gchar *work_string = g_strdup(ctl_line); - work_string = g_strdup(ctl_line); + /* strip trailing newline, and any other whitespace in front */ + g_strstrip(work_string); - /* strip trailing newline */ - len = strlen(ctl_line); - if (work_string[len - 1] == '\n') - ctlstrip = g_strndup(work_string, len - 1); - else - ctlstrip = g_strdup(work_string); - g_free(work_string); - - if( strcmp(g_strchug(ctlstrip), "") && - strcmp(exp_line = expand(ctlstrip, 0), "") + if( strcmp(work_string, "") && + strcmp(exp_line = expand(work_string, 0), "") ) { /* ignore comments */ if((exp_line[0] == '#')) @@ -1500,7 +1491,7 @@ parse_cmd_line(const char *ctl_line, GString *result) { g_free(exp_line); } - g_free(ctlstrip); + g_free(work_string); } /*@null@*/ gchar* -- cgit v1.2.3 From 9340e4f23264c7e820b52f18de5ca29132c68e72 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 13:46:31 -0700 Subject: refactor parse_command and parse_cmd_line --- src/uzbl-core.c | 241 +++++++++++++++++++++++++++++++------------------------- src/uzbl-core.h | 15 +++- 2 files changed, 145 insertions(+), 111 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 8f9ff88..ba6b4de 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -571,55 +571,55 @@ VIEWFUNC(go_forward) #undef VIEWFUNC /* -- command to callback/function map for things we cannot attach to any signals */ -struct {const char *key; CommandInfo value;} cmdlist[] = +CommandInfo cmdlist[] = { /* key function no_split */ - { "back", {view_go_back, 0} }, - { "forward", {view_go_forward, 0} }, - { "scroll", {scroll_cmd, 0} }, - { "reload", {view_reload, 0}, }, - { "reload_ign_cache", {view_reload_bypass_cache, 0} }, - { "stop", {view_stop_loading, 0}, }, - { "zoom_in", {view_zoom_in, 0}, }, //Can crash (when max zoom reached?). - { "zoom_out", {view_zoom_out, 0}, }, - { "toggle_zoom_type", {toggle_zoom_type, 0}, }, - { "uri", {load_uri, TRUE} }, - { "js", {run_js, TRUE} }, - { "script", {run_external_js, 0} }, - { "toggle_status", {toggle_status_cb, 0} }, - { "spawn", {spawn_async, 0} }, - { "sync_spawn", {spawn_sync, 0} }, // needed for cookie handler - { "sync_spawn_exec", {spawn_sync_exec, 0} }, // needed for load_cookies.sh :( - { "sh", {spawn_sh_async, 0} }, - { "sync_sh", {spawn_sh_sync, 0} }, // needed for cookie handler - { "exit", {close_uzbl, 0} }, - { "search", {search_forward_text, TRUE} }, - { "search_reverse", {search_reverse_text, TRUE} }, - { "search_clear", {search_clear, TRUE} }, - { "dehilight", {dehilight, 0} }, - { "set", {set_var, TRUE} }, - { "dump_config", {act_dump_config, 0} }, - { "dump_config_as_events", {act_dump_config_as_events, 0} }, - { "chain", {chain, 0} }, - { "print", {print, TRUE} }, - { "event", {event, TRUE} }, - { "request", {event, TRUE} }, - { "menu_add", {menu_add, TRUE} }, - { "menu_link_add", {menu_add_link, TRUE} }, - { "menu_image_add", {menu_add_image, TRUE} }, - { "menu_editable_add", {menu_add_edit, TRUE} }, - { "menu_separator", {menu_add_separator, TRUE} }, - { "menu_link_separator", {menu_add_separator_link, TRUE} }, - { "menu_image_separator", {menu_add_separator_image, TRUE}}, - { "menu_editable_separator", {menu_add_separator_edit, TRUE} }, - { "menu_remove", {menu_remove, TRUE} }, - { "menu_link_remove", {menu_remove_link, TRUE} }, - { "menu_image_remove", {menu_remove_image, TRUE} }, - { "menu_editable_remove", {menu_remove_edit, TRUE} }, - { "hardcopy", {hardcopy, TRUE} }, - { "include", {include, TRUE} }, - { "show_inspector", {show_inspector, 0} }, - { "add_cookie", {add_cookie, 0} }, - { "delete_cookie", {delete_cookie, 0} } + { "back", view_go_back, 0 }, + { "forward", view_go_forward, 0 }, + { "scroll", scroll_cmd, 0 }, + { "reload", view_reload, 0 }, + { "reload_ign_cache", view_reload_bypass_cache, 0 }, + { "stop", view_stop_loading, 0 }, + { "zoom_in", view_zoom_in, 0 }, //Can crash (when max zoom reached?). + { "zoom_out", view_zoom_out, 0 }, + { "toggle_zoom_type", toggle_zoom_type, 0 }, + { "uri", load_uri, TRUE }, + { "js", run_js, TRUE }, + { "script", run_external_js, 0 }, + { "toggle_status", toggle_status_cb, 0 }, + { "spawn", spawn_async, 0 }, + { "sync_spawn", spawn_sync, 0 }, // needed for cookie handler + { "sync_spawn_exec", spawn_sync_exec, 0 }, // needed for load_cookies.sh :( + { "sh", spawn_sh_async, 0 }, + { "sync_sh", spawn_sh_sync, 0 }, // needed for cookie handler + { "exit", close_uzbl, 0 }, + { "search", search_forward_text, TRUE }, + { "search_reverse", search_reverse_text, TRUE }, + { "search_clear", search_clear, TRUE }, + { "dehilight", dehilight, 0 }, + { "set", set_var, TRUE }, + { "dump_config", act_dump_config, 0 }, + { "dump_config_as_events", act_dump_config_as_events, 0 }, + { "chain", chain, 0 }, + { "print", print, TRUE }, + { "event", event, TRUE }, + { "request", event, TRUE }, + { "menu_add", menu_add, TRUE }, + { "menu_link_add", menu_add_link, TRUE }, + { "menu_image_add", menu_add_image, TRUE }, + { "menu_editable_add", menu_add_edit, TRUE }, + { "menu_separator", menu_add_separator, TRUE }, + { "menu_link_separator", menu_add_separator_link, TRUE }, + { "menu_image_separator", menu_add_separator_image, TRUE }, + { "menu_editable_separator", menu_add_separator_edit, TRUE }, + { "menu_remove", menu_remove, TRUE }, + { "menu_link_remove", menu_remove_link, TRUE }, + { "menu_image_remove", menu_remove_image, TRUE }, + { "menu_editable_remove", menu_remove_edit, TRUE }, + { "hardcopy", hardcopy, TRUE }, + { "include", include, TRUE }, + { "show_inspector", show_inspector, 0 }, + { "add_cookie", add_cookie, 0 }, + { "delete_cookie", delete_cookie, 0 } }; void @@ -629,7 +629,7 @@ commands_hash(void) uzbl.behave.commands = g_hash_table_new(g_str_hash, g_str_equal); for (i = 0; i < LENGTH(cmdlist); i++) - g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i].value); + g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i]); } void @@ -1141,15 +1141,15 @@ dehilight (WebKitWebView *page, GArray *argv, GString *result) { void chain (WebKitWebView *page, GArray *argv, GString *result) { - (void) page; (void) result; - gchar *a = NULL; - gchar **parts = NULL; + (void) page; guint i = 0; - while ((a = argv_idx(argv, i++))) { - parts = g_strsplit (a, " ", 2); - if (parts[0]) - parse_command(parts[0], parts[1], result); - g_strfreev (parts); + const gchar *cmd; + while ((cmd = argv_idx(argv, i++))) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + CommandInfo *c = parse_command_parts(cmd, a); + if (c) + run_parsed_command(c, a, result); + g_array_free (a, TRUE); } } @@ -1332,48 +1332,81 @@ spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { } void -parse_command(const char *cmd, const char *param, GString *result) { - CommandInfo *c; - GString *tmp = g_string_new(""); +run_parsed_command(CommandInfo *c, GArray *a, GString *result) { + c->function(uzbl.gui.web_view, a, result); - if ((c = g_hash_table_lookup(uzbl.behave.commands, cmd))) { - guint i; - gchar **par = split_quoted(param, TRUE); - GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + /* send the COMMAND_EXECUTED event, except for set and event/request commands */ + if(strcmp("set", c->key) && + strcmp("event", c->key) && + strcmp("request", c->key)) { + GString *tmp = g_string_new(c->key); + const gchar *p; + guint i = 0; + while ((p = argv_idx(a, i++))) + g_string_append_printf(tmp, " '%s'", p); + send_event(COMMAND_EXECUTED, tmp->str, NULL); + g_string_free(tmp, TRUE); + } +} - if (c->no_split) { /* don't split */ - sharg_append(a, param); - } else if (par) { - for (i = 0; i < g_strv_length(par); i++) - sharg_append(a, par[i]); - } +void +parse_command_arguments(const gchar *p, GArray *a, gboolean no_split) { + if (no_split && p) { /* pass the parameters through in one chunk */ + sharg_append(a, g_strdup(p)); + return; + } + + gchar **par = split_quoted(p, TRUE); + if (par) { + guint i; + for (i = 0; i < g_strv_length(par); i++) + sharg_append(a, g_strdup(par[i])); + g_strfreev (par); + } +} - if (result == NULL) { - GString *result_print = g_string_new(""); +CommandInfo * +parse_command_parts(const gchar *line, GArray *a) { + CommandInfo *c = NULL; - c->function(uzbl.gui.web_view, a, result_print); - if (result_print->len) - printf("%*s\n", (int)result_print->len, result_print->str); + gchar *exp_line = expand(line, 0); + if(exp_line[0] == '\0') + return NULL; - g_string_free(result_print, TRUE); - } else { - c->function(uzbl.gui.web_view, a, result); - } - g_strfreev (par); - g_array_free (a, TRUE); + /* separate the line into the command and its parameters */ + gchar **tokens = g_strsplit(exp_line, " ", 2); - if(strcmp("set", cmd) && - strcmp("event", cmd) && - strcmp("request", cmd)) { - g_string_printf(tmp, "%s %s", cmd, param?param:""); - send_event(COMMAND_EXECUTED, tmp->str, NULL); - } - } - else { - g_string_printf (tmp, "%s %s", cmd, param?param:""); - send_event(COMMAND_ERROR, tmp->str, NULL); + /* look up the command */ + c = g_hash_table_lookup(uzbl.behave.commands, tokens[0]); + + if(!c) { + send_event(COMMAND_ERROR, exp_line, NULL); + g_free(exp_line); + g_strfreev(tokens); + return NULL; } - g_string_free(tmp, TRUE); + + gchar *p = g_strdup(tokens[1]); + g_free(exp_line); + g_strfreev(tokens); + + /* parse the arguments */ + parse_command_arguments(p, a, c->no_split); + g_free(p); + + return c; +} + +void +parse_command(const char *cmd, const char *params, GString *result) { + CommandInfo *c = g_hash_table_lookup(uzbl.behave.commands, cmd); + + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + + parse_command_arguments(params, a, c->no_split); + run_parsed_command(c, a, result); + + g_array_free (a, TRUE); } @@ -1467,28 +1500,18 @@ set_var_value(const gchar *name, gchar *val) { void parse_cmd_line(const char *ctl_line, GString *result) { - gchar *exp_line = NULL; gchar *work_string = g_strdup(ctl_line); /* strip trailing newline, and any other whitespace in front */ g_strstrip(work_string); - if( strcmp(work_string, "") && - strcmp(exp_line = expand(work_string, 0), "") - ) { - /* ignore comments */ - if((exp_line[0] == '#')) - ; - - /* parse a command */ - else { - gchar **tokens = NULL; - - tokens = g_strsplit(exp_line, " ", 2); - parse_command(tokens[0], tokens[1], result); - g_strfreev(tokens); - } - g_free(exp_line); + if( strcmp(work_string, "") ) { + if((work_string[0] != '#')) { /* ignore comments */ + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + CommandInfo *c = parse_command_parts(work_string, a); + run_parsed_command(c, a, result); + g_array_free (a, TRUE); + } } g_free(work_string); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index f81722d..ef948ca 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -479,10 +479,21 @@ builtins(); typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); typedef struct { - Command function; - gboolean no_split; + const gchar *key; + Command function; + gboolean no_split; } CommandInfo; +CommandInfo * +parse_command_parts(const gchar *line, GArray *a); + +void +parse_command_arguments(const gchar *p, GArray *a, gboolean no_split); + +void +run_parsed_command(CommandInfo *c, GArray *a, GString *result); + + typedef struct { gchar *name; gchar *cmd; -- cgit v1.2.3 From 975e322d37afaca6e565b37282f2d9e6038124bc Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 12:11:19 -0700 Subject: add a variable @_ that expands to the result of the last sync command --- src/uzbl-core.c | 9 ++++++++- src/uzbl-core.h | 3 ++- tests/test-command.c | 17 +++++++++++++++++ 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index ba6b4de..8e14982 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -145,6 +145,7 @@ const struct var_name_to_ptr_t { { "SELECTED_URI", PTR_C_STR(uzbl.state.selected_url, NULL)}, { "NAME", PTR_C_STR(uzbl.state.instance_name, NULL)}, { "PID", PTR_C_STR(uzbl.info.pid_str, NULL)}, + { "_", PTR_C_STR(uzbl.state.last_result, NULL)}, { NULL, {.ptr.s = NULL, .type = TYPE_INT, .dump = 0, .writeable = 0, .func = NULL}} }; @@ -1347,6 +1348,11 @@ run_parsed_command(CommandInfo *c, GArray *a, GString *result) { send_event(COMMAND_EXECUTED, tmp->str, NULL); g_string_free(tmp, TRUE); } + + if(result) { + g_free(uzbl.state.last_result); + uzbl.state.last_result = g_strdup(result->str); + } } void @@ -2294,7 +2300,8 @@ initialize(int argc, char *argv[]) { uzbl.state.executable_path = g_strdup(argv[0]); uzbl.state.selected_url = NULL; - uzbl.state.searchtx = NULL; + uzbl.state.searchtx = NULL; + uzbl.state.last_result = NULL; GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default"); g_option_context_add_main_entries (context, entries, NULL); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index ef948ca..049053a 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -98,7 +98,8 @@ typedef struct { gchar *selected_url; gchar *last_selected_url; gchar *executable_path; - gchar* searchtx; + gchar *searchtx; + gchar *last_result; gboolean verbose; gboolean events_stdout; GPtrArray *event_buffer; diff --git a/tests/test-command.c b/tests/test-command.c index 7b33405..20c6aa0 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -281,6 +281,21 @@ test_js (void) { g_string_free(result, TRUE); } +void +test_last_result (void) { + GString *result = g_string_new(""); + + /* the last result gets set */ + parse_cmd_line("js -1", result); + g_assert_cmpstr("-1", ==, uzbl.state.last_result); + + /* the last result can be used in a chain */ + parse_cmd_line("chain 'js 1' 'js \\@_ + 1'", result); + g_assert_cmpstr("2", ==, uzbl.state.last_result); + + g_string_free(result, TRUE); +} + void test_run_handler_arg_order (void) { run_handler("sync_spawn echo uvw xyz", "abc def"); @@ -320,6 +335,8 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/js", test_js); + g_test_add_func("/test-command/last-result", test_last_result); + /* the following aren't really "command" tests, but they're not worth * splitting into a separate file yet */ g_test_add_func("/test-command/run_handler/arg-order", test_run_handler_arg_order); -- cgit v1.2.3 From 99961c4561f478523048ed69b37b37c432c42b8a Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 13 Jan 2011 17:41:08 -0700 Subject: kill run_handler, inject_handler_args, strfree and sync_stdout --- src/callbacks.c | 51 ++++++---- src/cookie-jar.c | 56 ++++++++--- src/uzbl-core.c | 271 ++++++++++++++++----------------------------------- src/uzbl-core.h | 12 +-- tests/test-command.c | 37 +------ 5 files changed, 166 insertions(+), 261 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index 7b06873..bc06a45 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -641,23 +641,26 @@ navigation_decision_cb (WebKitWebView *web_view, WebKitWebFrame *frame, WebKitNe printf("Navigation requested -> %s\n", uri); if (uzbl.behave.scheme_handler) { - GString *s = g_string_new (""); - g_string_printf(s, "'%s'", uri); + GString *result = g_string_new (""); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(uzbl.behave.scheme_handler, a); - run_handler(uzbl.behave.scheme_handler, s->str); + if(c) { + g_array_append_val(a, uri); + run_parsed_command(c, a, result); + } + g_array_free(a, TRUE); - if(uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) { - char *p = strchr(uzbl.comm.sync_stdout, '\n' ); + if(result->len > 0) { + char *p = strchr(result->str, '\n' ); if ( p != NULL ) *p = '\0'; - if (!strcmp(uzbl.comm.sync_stdout, "USED")) { + if (!strcmp(result->str, "USED")) { webkit_web_policy_decision_ignore(policy_decision); decision_made = TRUE; } } - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); - g_string_free(s, TRUE); + g_string_free(result, TRUE); } if (!decision_made) webkit_web_policy_decision_use(policy_decision); @@ -841,27 +844,35 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat (this may be inaccurate, there's nothing we can do about that.) */ unsigned int total_size = webkit_download_get_total_size(download); - gchar *ev = g_strdup_printf("'%s' '%s' '%s' %d", uri, suggested_filename, - content_type, total_size); - run_handler(uzbl.behave.download_handler, ev); - g_free(ev); - - /* no response, cancel the download */ - if(!uzbl.comm.sync_stdout) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(uzbl.behave.download_handler, a); + if(!c) { webkit_download_cancel(download); + g_array_free(a, TRUE); return FALSE; } + g_array_append_val(a, uri); + g_array_append_val(a, suggested_filename); + g_array_append_val(a, content_type); + gchar *total_size_s = g_strdup_printf("%d", total_size); + g_array_append_val(a, total_size_s); + + GString *result = g_string_new (""); + run_parsed_command(c, a, result); + + g_free(total_size_s); + g_array_free(a, TRUE); + /* no response, cancel the download */ - if(uzbl.comm.sync_stdout[0] == 0) { + if(result->len == 0) { webkit_download_cancel(download); - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); return FALSE; } /* we got a response, it's the path we should download the file to */ - gchar *destination_path = uzbl.comm.sync_stdout; - uzbl.comm.sync_stdout = NULL; + gchar *destination_path = result->str; + g_string_free(result, FALSE); /* presumably people don't need newlines in their filenames. */ char *p = strchr(destination_path, '\n'); diff --git a/src/cookie-jar.c b/src/cookie-jar.c index 626e454..9ddef3b 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -74,11 +74,11 @@ uzbl_cookie_jar_set_handler(UzblCookieJar *jar, const gchar* handler) { char *get_cookies(UzblCookieJar *jar, SoupURI *uri) { gchar *result, *path; - GString *s = g_string_new ("GET"); path = uri->path[0] ? uri->path : "/"; if(has_socket_handler(jar)) { + GString *s = g_string_new ("GET"); g_string_append_c(s, 0); /* null-terminate the GET */ g_string_append_len(s, uri->scheme, strlen(uri->scheme)+1); g_string_append_len(s, uri->host, strlen(uri->host)+1 ); @@ -88,13 +88,30 @@ char *get_cookies(UzblCookieJar *jar, SoupURI *uri) { /* try it again; older cookie daemons closed the connection after each request */ if(result == NULL) result = do_socket_request(jar, s->str, s->len); + + g_string_free(s, TRUE); } else { - g_string_append_printf(s, " '%s' '%s' '%s'", uri->scheme, uri->host, uri->path); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + + const CommandInfo *c = parse_command_parts(jar->handler, a); + if(!c) { + g_array_free(a, TRUE); + return NULL; + } - run_handler(jar->handler, s->str); - result = g_strdup(uzbl.comm.sync_stdout); + /* add our handler args */ + g_array_append_val(a, "GET"); + g_array_append_val(a, uri->scheme); + g_array_append_val(a, uri->host); + g_array_append_val(a, uri->path); + + GString *r = g_string_new (""); + run_parsed_command(c, a, r); + result = r->str; + g_string_free(r, FALSE); + g_array_free(a, TRUE); } - g_string_free(s, TRUE); + return result; } @@ -168,7 +185,7 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'", cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:""); - if(new_cookie) + if(new_cookie) send_event(ADD_COOKIE, eventstr, NULL); else send_event(DELETE_COOKIE, eventstr, NULL); @@ -182,9 +199,8 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { if(!new_cookie) return; - GString *s = g_string_new ("PUT"); - if(has_socket_handler(uzbl_jar)) { + GString *s = g_string_new ("PUT"); g_string_append_c(s, 0); /* null-terminate the PUT */ g_string_append_len(s, scheme, strlen(scheme)+1); g_string_append_len(s, new_cookie->domain, strlen(new_cookie->domain)+1 ); @@ -197,13 +213,29 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { result = do_socket_request(uzbl_jar, s->str, s->len+1); g_free(result); + g_string_free(s, TRUE); } else { - g_string_append_printf(s, " '%s' '%s' '%s' '%s=%s'", scheme, new_cookie->domain, new_cookie->path, new_cookie->name, new_cookie->value); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - run_handler(uzbl_jar->handler, s->str); - } + const CommandInfo *c = parse_command_parts(uzbl_jar->handler, a); + if(!c) { + g_array_free(a, TRUE); + return; + } + + g_array_append_val(a, "PUT"); + g_array_append_val(a, scheme); + g_array_append_val(a, new_cookie->domain); + g_array_append_val(a, new_cookie->path); - g_string_free(s, TRUE); + gchar *kv = g_strconcat(new_cookie->name, "=", new_cookie->value, NULL); + g_array_append_val(a, kv); + + run_parsed_command(c, a, NULL); + + g_free(kv); + g_array_free(a, TRUE); + } } static void diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 8e14982..0a90bb9 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -360,12 +360,6 @@ itos(int val) { return g_strdup(tmp); } -gchar* -strfree(gchar *str) { - g_free(str); - return NULL; -} - gchar* argv_idx(const GArray *a, const guint idx) { return g_array_index(a, gchar*, idx); } @@ -1119,7 +1113,8 @@ search_clear(WebKitWebView *page, GArray *argv, GString *result) { (void) result; webkit_web_view_unmark_text_matches (page); - uzbl.state.searchtx = strfree (uzbl.state.searchtx); + g_free(uzbl.state.searchtx); + uzbl.state.searchtx = NULL; } void @@ -1145,13 +1140,18 @@ chain (WebKitWebView *page, GArray *argv, GString *result) { (void) page; guint i = 0; const gchar *cmd; + GString *r = g_string_new (""); while ((cmd = argv_idx(argv, i++))) { GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - CommandInfo *c = parse_command_parts(cmd, a); + const CommandInfo *c = parse_command_parts(cmd, a); if (c) - run_parsed_command(c, a, result); + run_parsed_command(c, a, r); g_array_free (a, TRUE); } + if(result) + g_string_assign (result, r->str); + + g_string_free(r, TRUE); } void @@ -1185,7 +1185,8 @@ run_command (const gchar *command, const gchar **args, const gboolean sync, gboolean result; if (sync) { - if (*output_stdout) *output_stdout = strfree(*output_stdout); + if (*output_stdout) + g_free(*output_stdout); result = g_spawn_sync(NULL, (gchar **)a->data, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, output_stdout, NULL, NULL, &err); @@ -1253,25 +1254,28 @@ split_quoted(const gchar* src, const gboolean unquote) { } void -spawn(GArray *argv, gboolean sync, gboolean exec) { +spawn(GArray *argv, GString *result, gboolean exec) { gchar *path = NULL; gchar *arg_car = argv_idx(argv, 0); const gchar **arg_cdr = &g_array_index(argv, const gchar *, 1); if (arg_car && (path = find_existing_file(arg_car))) { - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); - run_command(path, arg_cdr, sync, sync?&uzbl.comm.sync_stdout:NULL); - // run each line of output from the program as a command - if (sync && exec && uzbl.comm.sync_stdout) { - gchar *head = uzbl.comm.sync_stdout; - gchar *tail; - while ((tail = strchr (head, '\n'))) { - *tail = '\0'; - parse_cmd_line(head, NULL); - head = tail + 1; + gchar *r = NULL; + run_command(path, arg_cdr, result != NULL, result ? &r : NULL); + if(result) { + g_string_assign(result, r); + // run each line of output from the program as a command + if (exec && r) { + gchar *head = r; + gchar *tail; + while ((tail = strchr (head, '\n'))) { + *tail = '\0'; + parse_cmd_line(head, NULL); + head = tail + 1; + } } } + g_free(r); g_free(path); } } @@ -1279,23 +1283,28 @@ spawn(GArray *argv, gboolean sync, gboolean exec) { void spawn_async(WebKitWebView *web_view, GArray *argv, GString *result) { (void)web_view; (void)result; - spawn(argv, FALSE, FALSE); + spawn(argv, NULL, FALSE); } void spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn(argv, TRUE, FALSE); + (void)web_view; + spawn(argv, result, FALSE); } void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result) { - (void)web_view; (void)result; - spawn(argv, TRUE, TRUE); + (void)web_view; + if(!result) { + GString *force_result = g_string_new(""); + spawn(argv, force_result, TRUE); + g_string_free (force_result, TRUE); + } else + spawn(argv, result, TRUE); } void -spawn_sh(GArray *argv, gboolean sync) { +spawn_sh(GArray *argv, GString *result) { if (!uzbl.behave.shell_cmd) { g_printerr ("spawn_sh: shell_cmd is not set!\n"); return; @@ -1303,19 +1312,23 @@ spawn_sh(GArray *argv, gboolean sync) { guint i; gchar **cmd = split_quoted(uzbl.behave.shell_cmd, TRUE); + if(!cmd) + return; + gchar *cmdname = g_strdup(cmd[0]); g_array_insert_val(argv, 1, cmdname); for (i = 1; i < g_strv_length(cmd); i++) g_array_prepend_val(argv, cmd[i]); - if (cmd) { - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); + if (result) { + gchar *r = NULL; + run_command(cmd[0], (const gchar **) argv->data, TRUE, &r); + g_string_assign(result, r); + g_free(r); + } else + run_command(cmd[0], (const gchar **) argv->data, FALSE, NULL); - run_command(cmd[0], (const gchar **) argv->data, - sync, sync?&uzbl.comm.sync_stdout:NULL); - } g_free (cmdname); g_strfreev (cmd); } @@ -1323,17 +1336,17 @@ spawn_sh(GArray *argv, gboolean sync) { void spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result) { (void)web_view; (void)result; - spawn_sh(argv, FALSE); + spawn_sh(argv, NULL); } void spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result) { (void)web_view; (void)result; - spawn_sh(argv, TRUE); + spawn_sh(argv, result); } void -run_parsed_command(CommandInfo *c, GArray *a, GString *result) { +run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { c->function(uzbl.gui.web_view, a, result); /* send the COMMAND_EXECUTED event, except for set and event/request commands */ @@ -1350,8 +1363,8 @@ run_parsed_command(CommandInfo *c, GArray *a, GString *result) { } if(result) { - g_free(uzbl.state.last_result); - uzbl.state.last_result = g_strdup(result->str); + g_free(uzbl.state.last_result); + uzbl.state.last_result = g_strdup(result->str); } } @@ -1371,7 +1384,7 @@ parse_command_arguments(const gchar *p, GArray *a, gboolean no_split) { } } -CommandInfo * +const CommandInfo * parse_command_parts(const gchar *line, GArray *a) { CommandInfo *c = NULL; @@ -1406,13 +1419,18 @@ parse_command_parts(const gchar *line, GArray *a) { void parse_command(const char *cmd, const char *params, GString *result) { CommandInfo *c = g_hash_table_lookup(uzbl.behave.commands, cmd); + if(c) { + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - - parse_command_arguments(params, a, c->no_split); - run_parsed_command(c, a, result); + parse_command_arguments(params, a, c->no_split); + run_parsed_command(c, a, result); - g_array_free (a, TRUE); + g_array_free (a, TRUE); + } else { + gchar *tmp = g_strconcat(cmd, " ", params, NULL); + send_event(COMMAND_ERROR, tmp, NULL); + g_free(tmp); + } } @@ -1514,7 +1532,7 @@ parse_cmd_line(const char *ctl_line, GString *result) { if( strcmp(work_string, "") ) { if((work_string[0] != '#')) { /* ignore comments */ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - CommandInfo *c = parse_command_parts(work_string, a); + const CommandInfo *c = parse_command_parts(work_string, a); run_parsed_command(c, a, result); g_array_free (a, TRUE); } @@ -1985,126 +2003,6 @@ create_plug () { return plug; } - -gchar** -inject_handler_args(const gchar *actname, const gchar *origargs, const gchar *newargs) { - /* - If actname is one that calls an external command, this function will inject - newargs in front of the user-provided args in that command line. They will - come become after the body of the script (in sh) or after the name of - the command to execute (in spawn). - i.e. sh becomes sh and - spawn becomes spawn . - - The return value consist of two strings: the action (sh, ...) and its args. - - If act is not one that calls an external command, then the given action merely - gets duplicated. - */ - GArray *rets = g_array_new(TRUE, FALSE, sizeof(gchar*)); - /* Arrr! Here be memory leaks */ - gchar *actdup = g_strdup(actname); - g_array_append_val(rets, actdup); - - if ((g_strcmp0(actname, "spawn") == 0) || - (g_strcmp0(actname, "sh") == 0) || - (g_strcmp0(actname, "sync_spawn") == 0) || - (g_strcmp0(actname, "sync_sh") == 0)) { - guint i; - GString *a = g_string_new(""); - gchar **spawnparts = split_quoted(origargs, FALSE); - g_string_append_printf(a, "%s", spawnparts[0]); /* sh body or script name */ - if (newargs) g_string_append_printf(a, " %s", newargs); /* handler args */ - - for (i = 1; i < g_strv_length(spawnparts); i++) /* user args */ - if (spawnparts[i]) g_string_append_printf(a, " %s", spawnparts[i]); - - g_array_append_val(rets, a->str); - g_string_free(a, FALSE); - g_strfreev(spawnparts); - } else { - gchar *origdup = g_strdup(origargs); - g_array_append_val(rets, origdup); - } - return (gchar**)g_array_free(rets, FALSE); -} - -void -run_handler (const gchar *act, const gchar *args) { - /* Consider this code a temporary hack to make the handlers usable. - In practice, all this splicing, injection, and reconstruction is - inefficient, annoying and hard to manage. Potential pitfalls arise - when the handler specific args 1) are not quoted (the handler - callbacks should take care of this) 2) are quoted but interfere - with the users' own quotation. A more ideal solution is - to refactor parse_command so that it doesn't just take a string - and execute it; rather than that, we should have a function which - returns the argument vector parsed from the string. This vector - could be modified (e.g. insert additional args into it) before - passing it to the next function that actually executes it. Though - it still isn't perfect for chain actions.. will reconsider & re- - factor when I have the time. -duc */ - - if (!act) return; - char **parts = g_strsplit(act, " ", 2); - if (!parts || !parts[0]) return; - if (g_strcmp0(parts[0], "chain") == 0) { - GString *newargs = g_string_new(""); - gchar **chainparts = split_quoted(parts[1], FALSE); - - /* for every argument in the chain, inject the handler args - and make sure the new parts are wrapped in quotes */ - gchar **cp = chainparts; - gchar quot = '\''; - gchar *quotless = NULL; - gchar **spliced_quotless = NULL; // sigh -_-; - gchar **inpart = NULL; - - while (*cp) { - if ((**cp == '\'') || (**cp == '\"')) { /* strip old quotes */ - quot = **cp; - quotless = g_strndup(&(*cp)[1], strlen(*cp) - 2); - } else quotless = g_strdup(*cp); - - spliced_quotless = g_strsplit(quotless, " ", 2); - inpart = inject_handler_args(spliced_quotless[0], spliced_quotless[1], args); - g_strfreev(spliced_quotless); - - g_string_append_printf(newargs, " %c%s %s%c", quot, inpart[0], inpart[1], quot); - g_free(quotless); - g_strfreev(inpart); - cp++; - } - - parse_command(parts[0], &(newargs->str[1]), NULL); - g_string_free(newargs, TRUE); - g_strfreev(chainparts); - - } else { - gchar **inparts; - gchar *inparts_[2]; - if (parts[1]) { - /* expand the user-specified arguments */ - gchar* expanded = expand(parts[1], 0); - inparts = inject_handler_args(parts[0], expanded, args); - g_free(expanded); - } else { - inparts_[0] = parts[0]; - inparts_[1] = g_strdup(args); - inparts = inparts_; - } - - parse_command(inparts[0], inparts[1], NULL); - - if (inparts != inparts_) { - g_free(inparts[0]); - g_free(inparts[1]); - } else - g_free(inparts[1]); - } - g_strfreev(parts); -} - void settings_init () { State *s = &uzbl.state; @@ -2145,32 +2043,34 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au (void) user_data; if(uzbl.behave.authentication_handler && *uzbl.behave.authentication_handler != 0) { - gchar *info, *host, *realm; - gchar *p; - soup_session_pause_message(session, msg); - /* Sanitize strings */ - info = g_strdup(soup_auth_get_info(auth)); - host = g_strdup(soup_auth_get_host(auth)); - realm = g_strdup(soup_auth_get_realm(auth)); - for (p = info; *p; p++) if (*p == '\'') *p = '\"'; - for (p = host; *p; p++) if (*p == '\'') *p = '\"'; - for (p = realm; *p; p++) if (*p == '\'') *p = '\"'; + GString *result = g_string_new (""); - GString *s = g_string_new (""); - g_string_printf(s, "'%s' '%s' '%s' '%s'", - info, host, realm, retrying?"TRUE":"FALSE"); + gchar *info = g_strdup(soup_auth_get_info(auth)); + gchar *host = g_strdup(soup_auth_get_host(auth)); + gchar *realm = g_strdup(soup_auth_get_realm(auth)); - run_handler(uzbl.behave.authentication_handler, s->str); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + const CommandInfo *c = parse_command_parts(uzbl.behave.authentication_handler, a); + if(c) { + sharg_append(a, info); + sharg_append(a, host); + sharg_append(a, realm); + sharg_append(a, retrying ? "TRUE" : "FALSE"); - if (uzbl.comm.sync_stdout && strcmp (uzbl.comm.sync_stdout, "") != 0) { + run_parsed_command(c, a, result); + } + g_array_free(a, TRUE); + + if (result->len > 0) { char *username, *password; int number_of_endls=0; - username = uzbl.comm.sync_stdout; + username = result->str; - for (p = uzbl.comm.sync_stdout; *p; p++) { + gchar *p; + for (p = result->str; *p; p++) { if (*p == '\n') { *p = '\0'; if (++number_of_endls == 1) @@ -2184,12 +2084,9 @@ void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *au soup_auth_authenticate(auth, username, password); } - if (uzbl.comm.sync_stdout) - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); - soup_session_unpause_message(session, msg); - g_string_free(s, TRUE); + g_string_free(result, TRUE); g_free(info); g_free(host); g_free(realm); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 049053a..14b0571 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -83,7 +83,6 @@ typedef struct { /* stores (key)"variable name" -> (value)"pointer to var*/ GHashTable *proto_var; - gchar *sync_stdout; GPtrArray *connect_chan; GPtrArray *client_chan; } Communication; @@ -237,9 +236,6 @@ typedef struct { char * itos(int val); -gchar* -strfree(gchar *str); - void clean_up(void); @@ -343,9 +339,6 @@ create_window (); GtkPlug* create_plug (); -void -run_handler (const gchar *act, const gchar *args); - void settings_init (); @@ -485,15 +478,14 @@ typedef struct { gboolean no_split; } CommandInfo; -CommandInfo * +const CommandInfo * parse_command_parts(const gchar *line, GArray *a); void parse_command_arguments(const gchar *p, GArray *a, gboolean no_split); void -run_parsed_command(CommandInfo *c, GArray *a, GString *result); - +run_parsed_command(const CommandInfo *c, GArray *a, GString *result); typedef struct { gchar *name; diff --git a/tests/test-command.c b/tests/test-command.c index 20c6aa0..d07bf79 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -263,11 +263,12 @@ test_toggle_status (void) { void test_sync_sh (void) { - parse_cmd_line("sync_sh 'echo Test echo.'", NULL); - g_assert_cmpstr("Test echo.\n", ==, uzbl.comm.sync_stdout); + GString *result = g_string_new(""); + + parse_cmd_line("sync_sh 'echo Test echo.'", result); + g_assert_cmpstr("Test echo.\n", ==, result->str); - /* clean up after ourselves */ - uzbl.comm.sync_stdout = strfree(uzbl.comm.sync_stdout); + g_string_free(result, TRUE); } void @@ -296,29 +297,6 @@ test_last_result (void) { g_string_free(result, TRUE); } -void -test_run_handler_arg_order (void) { - run_handler("sync_spawn echo uvw xyz", "abc def"); - - assert(uzbl.comm.sync_stdout); - - /* the rest of the result should be the arguments passed to run_handler. */ - /* the arguments in the second argument to run_handler should be placed before any - * included in the first argument to run handler. */ - g_assert_cmpstr("abc def uvw xyz\n", ==, uzbl.comm.sync_stdout); -} - -void -test_run_handler_expand (void) { - uzbl.net.useragent = "Test uzbl uzr agent"; - run_handler("sync_spawn echo @useragent", "result:"); - - assert(uzbl.comm.sync_stdout); - - /* the user-specified arguments to the handler should have been expanded */ - g_assert_cmpstr("result: Test uzbl uzr agent\n", ==, uzbl.comm.sync_stdout); -} - int main (int argc, char *argv[]) { /* set up tests */ @@ -337,11 +315,6 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/last-result", test_last_result); - /* the following aren't really "command" tests, but they're not worth - * splitting into a separate file yet */ - g_test_add_func("/test-command/run_handler/arg-order", test_run_handler_arg_order); - g_test_add_func("/test-command/run_handler/expand", test_run_handler_expand); - /* set up uzbl */ initialize(argc, argv); -- cgit v1.2.3 From 6a737a7137c8cfbbe21bb5f0c0182ca2255a5b4c Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 17 Jan 2011 21:37:08 +0100 Subject: multiple components/re -pairs in cookie filters --- README | 4 ++-- docs/README.uzbl-event-manager | 20 ++++++++++---------- examples/config/config | 6 +++++- examples/data/plugins/cookies.py | 28 ++++++++++++++++++---------- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/README b/README index a8c500c..d20cbd2 100644 --- a/README +++ b/README @@ -770,12 +770,12 @@ Events/requests which the EM and its plugins listens for move the cursor back by one character. * `START_COMPLETION`: TODO explain completion * `BLACKLIST_COOKIE`: add a rule for blacklisting cookies - - `request BLACKLIST_COOKIE `: Blacklist cookies where + - `request BLACKLIST_COOKIE [ ]*`: Blacklist cookies where `` matches ``. `` is one of `domain`, `path`, `name`, `value`, `scheme` or `expires`. * `WHITELIST_COOKIE`: add a rule for whitelisting cookies (if any whitelist is set then only cookies that are whitelisted cookies will be used) - - `request WHITELIST_COOKIE `: Whitelist cookies where + - `request WHITELIST_COOKIE [ ]*`: Whitelist cookies where `` matches ``. `` is one of `domain`, `path`, `name`, `value`, `scheme` or `expires`. diff --git a/docs/README.uzbl-event-manager b/docs/README.uzbl-event-manager index 074811e..b9467d7 100644 --- a/docs/README.uzbl-event-manager +++ b/docs/README.uzbl-event-manager @@ -83,17 +83,17 @@ events. If any whitelist is set, then any cookie that is not whitelisted will be rejected. Otherwise, only cookies that have been blacklisted will be rejected. -BLACKLIST_COOKIE - Adds a new blacklist filter. cookies where the component specified by - `part` matches the regular expression `re` will be filtered. part can be - either 0-5 or any of the symbolic names domain, path, name, value, scheme, - expires +BLACKLIST_COOKIE [ ]* + Adds a new blacklist filter. cookies where the components specified by + `component` matches the regular expression `re` will be filtered. component + may be either 0-5 or any of the symbolic names domain, path, name, value, + scheme, expires - for example to block all cookies which name is "__utm" followed by a single + for example to block all cookies which name is "__utm" followed by a single character (google analytics cookies) do. request BLACKLIST_COOKIE name '^__utm.$' -WHITELIST_COOKIE - Adds a new whitelist filter. cookies where the component specified by - `part` matches the regular expression `re` will be allowed. part can be any - of the parts allowed for the BLACKLIST_COOKIE event +WHITELIST_COOKIE [ ]* + Adds a new whitelist filter. cookies where the components specified by + `component` matches the regular expression `re` will be allowed. component + may be any of the components allowed for the BLACKLIST_COOKIE event diff --git a/examples/config/config b/examples/config/config index a2ecdb8..bdf1c00 100644 --- a/examples/config/config +++ b/examples/config/config @@ -129,7 +129,11 @@ set progress.pending = set useragent = Uzbl (Webkit @{WEBKIT_MAJOR}.@{WEBKIT_MINOR}) (@(+uname -sm)@ [@ARCH_UZBL]) # === Configure cookie blacklist ======================================================== -# Drop google analytics tracking cookies + +# Accept 'session cookies' from uzbl.org (when you have a whitelist all other cookies are dropped) +#request WHITELIST_COOKIE domain 'uzbl.org$' expires '^$' + +# Drop google analytics tracking cookies (applied after whitelists if any) #request BLACKLIST_COOKIE name '^__utm.$' # === Key binding configuration ============================================== diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index 9eccace..6ee8798 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -106,8 +106,11 @@ DefaultStore = TextStore(os.path.join(xdg_data_home, 'uzbl/cookies.txt')) SessionStore = TextStore(os.path.join(xdg_data_home, 'uzbl/session-cookies.txt')) def match_list(_list, cookie): - for component, match in _list: - if match(cookie[component]) is not None: + for matcher in _list: + for component, match in matcher: + if match(cookie[component]) is None: + break + else: return True return False @@ -158,18 +161,21 @@ def delete_cookie(uzbl, cookie): store.delete_cookie(cookie, splitted) # add a cookie matcher to a whitelist or a blacklist. -# a matcher is a (component, re) tuple that matches a cookie when the +# a matcher is a list of (component, re) tuples that matches a cookie when the # "component" part of the cookie matches the regular expression "re". # "component" is one of the keys defined in the variable "symbolic" above, # or the index of a component of a cookie tuple. def add_cookie_matcher(_list, arg): - component, regexp = splitquoted(arg) - try: - component = symbolic[component] - except KeyError: - component = int(component) - assert component <= 5 - _list.append((component, re.compile(regexp).search)) + args = splitquoted(arg) + mlist = [] + for (component, regexp) in zip(args[0::2], args[1::2]): + try: + component = symbolic[component] + except KeyError: + component = int(component) + assert component <= 5 + mlist.append((component, re.compile(regexp).search)) + _list.append(mlist) def blacklist(uzbl, arg): add_cookie_matcher(uzbl.cookie_blacklist, arg) @@ -188,3 +194,5 @@ def init(uzbl): 'cookie_blacklist' : [], 'cookie_whitelist' : [] }) + +# vi: set et ts=4: -- cgit v1.2.3 From f93cce44561b2475965c91419e72895bc368918e Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 16:59:49 +0100 Subject: disable keycmd reset on mode change * makes history search work * adds new KEYCMD_CLEAR event * configure to clear keycmd on ESCAPE event --- examples/config/config | 1 + examples/data/plugins/bind.py | 3 ++- examples/data/plugins/history.py | 3 +++ examples/data/plugins/keycmd.py | 5 ++++- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/examples/config/config b/examples/config/config index 4934469..2fea0d7 100644 --- a/examples/config/config +++ b/examples/config/config @@ -172,6 +172,7 @@ set ebind = @mode_bind global,-insert # Resets keycmd and returns to default mode. @on_event ESCAPE @set_mode +@on_event ESCAPE event KEYCMD_CLEAR @bind = event ESCAPE @bind [ = event ESCAPE diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index bf693b3..261dc5d 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -379,7 +379,6 @@ def mode_changed(uzbl, mode): if mode != 'stack': uzbl.bindlet.reset() - uzbl.clear_keycmd() def match_and_exec(uzbl, bind, depth, keylet, bindlet): @@ -470,3 +469,5 @@ def init(uzbl): 'mode_bind': mode_bind, 'bindlet': Bindlet(uzbl), }) + +# vi: set et ts=4: diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 78a94ce..2ab2ce3 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -107,6 +107,7 @@ def history_next(uzbl, _x): def history_search(uzbl, key): uzbl.history.search(key) + uzbl.send('event HISTORY_PREV') uzbl.logger.debug('SEARCH %s %s' % (key, uzbl.history)) end_messages = ('Look behind you, A three-headed monkey!', 'error #4: static from nylon underwear.', 'error #5: static from plastic slide rules.', 'error #6: global warming.', 'error #9: doppler effect.', 'error #16: somebody was calculating pi on the server.', 'error #19: floating point processor overflow.', 'error #21: POSIX compliance problem.', 'error #25: Decreasing electron flux.', 'error #26: first Saturday after first full moon in Winter.', 'error #64: CPU needs recalibration.', 'error #116: the real ttys became pseudo ttys and vice-versa.', 'error #229: wrong polarity of neutron flow.', 'error #330: quantum decoherence.', 'error #388: Bad user karma.', 'error #407: Route flapping at the NAP.', 'error #435: Internet shut down due to maintenance.') @@ -127,3 +128,5 @@ def init(uzbl): # plugin after hook def after(uzbl): uzbl.on_set('keycmd_prompt', lambda uzbl, k, v: uzbl.history.change_prompt(v)) + +# vi: set et ts=4: diff --git a/examples/data/plugins/keycmd.py b/examples/data/plugins/keycmd.py index 2fb2283..928c597 100644 --- a/examples/data/plugins/keycmd.py +++ b/examples/data/plugins/keycmd.py @@ -210,7 +210,7 @@ def modkey_addition_parse(uzbl, modkeys): add_modkey_addition(uzbl, keys[:-1], keys[-1]) -def clear_keycmd(uzbl): +def clear_keycmd(uzbl, *args): '''Clear the keycmd for this uzbl instance.''' k = uzbl.keylet @@ -493,6 +493,7 @@ def init(uzbl): 'KEYCMD_DELETE': keycmd_delete, 'KEYCMD_EXEC_CURRENT': keycmd_exec_current, 'KEYCMD_STRIP_WORD': keycmd_strip_word, + 'KEYCMD_CLEAR': clear_keycmd, 'KEY_PRESS': key_press, 'KEY_RELEASE': key_release, 'MODKEY_ADDITION': modkey_addition_parse, @@ -514,3 +515,5 @@ def init(uzbl): 'set_cursor_pos': set_cursor_pos, 'set_keycmd': set_keycmd, }) + +# vi: set et ts=4: -- cgit v1.2.3 From fc33a2fc3c27da78edb3db5c437e72537f718315 Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 18:42:40 +0100 Subject: with gtk3: fix setting of background color --- src/callbacks.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index fa2ed1f..8cfb073 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -47,15 +47,20 @@ set_authentication_handler() { void set_status_background() { - GdkColor color; - gdk_color_parse (uzbl.behave.status_background, &color); /* labels and hboxes do not draw their own background. applying this * on the vbox/main_window is ok as the statusbar is the only affected * widget. (if not, we could also use GtkEventBox) */ - if (uzbl.gui.main_window) - gtk_widget_modify_bg (uzbl.gui.main_window, GTK_STATE_NORMAL, &color); - else if (uzbl.gui.plug) - gtk_widget_modify_bg (GTK_WIDGET(uzbl.gui.plug), GTK_STATE_NORMAL, &color); + GtkWidget* widget = uzbl.gui.main_window ? uzbl.gui.main_window : GTK_WIDGET (uzbl.gui.plug); + +#if GTK_CHECK_VERSION(2,91,0) + GdkRGBA color; + gdk_rgba_parse (&color, uzbl.behave.status_background); + gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, &color); +#else + GdkColor color; + gdk_color_parse (uzbl.behave.status_background, &color); + gtk_widget_modify_bg (widget, GTK_STATE_NORMAL, &color); +#endif } void -- cgit v1.2.3 From 42ead959c23fdaacb530744139be2bb94600be3d Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 21:14:42 +0100 Subject: clear keycmd after following link in follow.sh --- examples/data/scripts/follow.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/data/scripts/follow.sh b/examples/data/scripts/follow.sh index d1560bf..d7fe117 100755 --- a/examples/data/scripts/follow.sh +++ b/examples/data/scripts/follow.sh @@ -17,5 +17,5 @@ case $result in echo 'event FORM_ACTIVE' > "$UZBL_FIFO" ;; *XXXRESET_MODEXXX*) # a link was selected, reset uzbl's input mode - echo 'set mode=' > "$UZBL_FIFO" ;; + printf 'set mode=\nevent KEYCMD_CLEAR\n' > "$UZBL_FIFO" ;; esac -- cgit v1.2.3 From 7fbebb427be655ee17de0b786e0ce9a3d86ea3d8 Mon Sep 17 00:00:00 2001 From: koral Date: Wed, 2 Feb 2011 16:25:54 +0100 Subject: Cleaning/commenting uzbl-core.h. --- src/callbacks.c | 8 +- src/util.c | 3 + src/util.h | 15 +- src/uzbl-core.h | 442 +++++++++++++++++++++----------------------------------- 4 files changed, 182 insertions(+), 286 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index 7b06873..f6fe284 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -8,11 +8,12 @@ #include "events.h" #include "util.h" + void set_proxy_url() { SoupURI *suri; - if(uzbl.net.proxy_url == NULL || *uzbl.net.proxy_url == ' ') { + if (uzbl.net.proxy_url == NULL || *uzbl.net.proxy_url == ' ') { soup_session_remove_feature_by_type(uzbl.net.soup_session, (GType) SOUP_SESSION_PROXY_URI); } @@ -23,9 +24,11 @@ set_proxy_url() { suri, NULL); soup_uri_free(suri); } + return; } + void set_authentication_handler() { /* Check if WEBKIT_TYPE_SOUP_AUTH_DIALOG feature is set */ @@ -45,10 +48,12 @@ set_authentication_handler() { return; } + void set_status_background() { GdkColor color; gdk_color_parse (uzbl.behave.status_background, &color); + /* labels and hboxes do not draw their own background. applying this * on the vbox/main_window is ok as the statusbar is the only affected * widget. (if not, we could also use GtkEventBox) */ @@ -58,6 +63,7 @@ set_status_background() { gtk_widget_modify_bg (GTK_WIDGET(uzbl.gui.plug), GTK_STATE_NORMAL, &color); } + void set_icon() { if(file_exists(uzbl.gui.icon)) { diff --git a/src/util.c b/src/util.c index c9c728e..458c04f 100644 --- a/src/util.c +++ b/src/util.c @@ -108,3 +108,6 @@ for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void * return FALSE; } + + + diff --git a/src/util.h b/src/util.h index f03f13e..06531bb 100644 --- a/src/util.h +++ b/src/util.h @@ -5,14 +5,9 @@ typedef struct { gchar* default_value; } XDG_Var; -gchar* get_xdg_var (XDG_Var xdg); -gchar* find_xdg_file (int xdg_type, const char* filename); - -gboolean file_exists(const char* filename); - -char * -str_replace (const char* search, const char* replace, const char* string); - -gboolean -for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); +gchar* get_xdg_var(XDG_Var xdg); +gchar* find_xdg_file(int xdg_type, const char* filename); +gboolean file_exists(const char* filename); +char* str_replace(const char* search, const char* replace, const char* string); +gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index f81722d..87f5ea9 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -44,8 +44,10 @@ #define LENGTH(x) (sizeof x / sizeof x[0]) -/* gui elements */ + +/* GUI elements */ typedef struct { + /* Window */ GtkWidget* main_window; gchar* geometry; GtkPlug* plug; @@ -57,31 +59,33 @@ typedef struct { GtkWidget* mainbar_label_left; GtkWidget* mainbar_label_right; - GtkScrollbar* scbar_v; // Horizontal and Vertical Scrollbar - GtkScrollbar* scbar_h; // (These are still hidden) - GtkAdjustment* bar_v; // Information about document length - GtkAdjustment* bar_h; // and scrolling position + /* Scrolling */ + GtkScrollbar* scbar_v; /* Horizontal and Vertical Scrollbar */ + GtkScrollbar* scbar_h; /* (These are still hidden) */ + GtkAdjustment* bar_v; /* Information about document length */ + GtkAdjustment* bar_h; /* and scrolling position */ int scrollbars_visible; + + /* Web page */ WebKitWebView* web_view; gchar* main_title; gchar* icon; /* WebInspector */ - GtkWidget *inspector_window; - WebKitWebInspector *inspector; + GtkWidget* inspector_window; + WebKitWebInspector* inspector; - /* custom context menu item */ + /* Custom context menu item */ GPtrArray *menu_items; } GUI; -/* external communication*/ +/* External communication */ enum { FIFO, SOCKET}; typedef struct { gchar *fifo_path; gchar *socket_path; - /* stores (key)"variable name" -> (value)"pointer to var*/ - GHashTable *proto_var; + GHashTable *proto_var; /* stores (key)"variable name" -> (value)"pointer to var */ gchar *sync_stdout; GPtrArray *connect_chan; @@ -89,68 +93,77 @@ typedef struct { } Communication; -/* internal state */ +/* Internal state */ typedef struct { - gchar *uri; - gchar *config_file; - int socket_id; - char *instance_name; - gchar *selected_url; - gchar *last_selected_url; - gchar *executable_path; - gchar* searchtx; - gboolean verbose; - gboolean events_stdout; - GPtrArray *event_buffer; - gchar** connect_socket_names; - GdkEventButton *last_button; - gboolean plug_mode; + gchar* uri; + gchar* config_file; + char* instance_name; + gchar* selected_url; + gchar* last_selected_url; + gchar* executable_path; + gchar* searchtx; + gboolean verbose; + GdkEventButton* last_button; + gboolean plug_mode; + + /* Events */ + int socket_id; + gboolean events_stdout; + GPtrArray* event_buffer; + gchar** connect_socket_names; } State; -/* networking */ +/* Networking */ typedef struct { - SoupSession *soup_session; - UzblCookieJar *soup_cookie_jar; - SoupLogger *soup_logger; - char *proxy_url; - char *useragent; - char *accept_languages; - gint max_conns; - gint max_conns_host; + SoupSession* soup_session; + UzblCookieJar* soup_cookie_jar; + SoupLogger* soup_logger; + char* proxy_url; + char* useragent; + char* accept_languages; + gint max_conns; + gint max_conns_host; } Network; -/* behaviour */ +/* Behaviour */ typedef struct { /* Status bar */ gchar* status_format; gchar* status_format_right; gchar* status_background; + gboolean show_status; + gboolean status_top; /* Window title */ gchar* title_format_short; gchar* title_format_long; + /* Communication */ gchar* fifo_dir; gchar* socket_dir; + + /* Handlers */ gchar* cookie_handler; gchar* authentication_handler; + gchar* scheme_handler; + gchar* download_handler; + + /* Fonts */ gchar* default_font_family; gchar* monospace_font_family; gchar* sans_serif_font_family; gchar* serif_font_family; gchar* fantasy_font_family; gchar* cursive_font_family; - gchar* scheme_handler; - gchar* download_handler; - gboolean show_status; + gboolean forward_keys; - gboolean status_top; guint modmask; guint http_debug; gchar* shell_cmd; guint view_source; + /* WebKitWebSettings exports */ guint font_size; guint monospace_size; @@ -176,31 +189,34 @@ typedef struct { gchar* base_url; gboolean print_version; - /* command list: (key)name -> (value)Command */ /* command list: (key)name -> (value)Command */ GHashTable* commands; + /* event lookup: (key)event_id -> (value)event_name */ GHashTable *event_lookup; } Behaviour; -/* javascript */ + +/* Javascript */ typedef struct { gboolean initialized; JSClassDefinition classdef; JSClassRef classref; } Javascript; -/* static information */ + +/* Static information */ typedef struct { - int webkit_major; - int webkit_minor; - int webkit_micro; - gchar *arch; - gchar *commit; - gchar *pid_str; + int webkit_major; + int webkit_minor; + int webkit_micro; + gchar* arch; + gchar* commit; + gchar* pid_str; } Info; -/* main uzbl data structure */ + +/* Main uzbl data structure */ typedef struct { GUI gui; State state; @@ -213,12 +229,12 @@ typedef struct { Window xwin; } UzblCore; -/* Main Uzbl object */ -extern UzblCore uzbl; +extern UzblCore uzbl; /* Main Uzbl object */ + typedef void sigfunc(int); -/* uzbl variables */ +/* Uzbl variables */ enum ptr_type {TYPE_INT, TYPE_STR, TYPE_FLOAT}; typedef struct { enum ptr_type type; @@ -232,262 +248,138 @@ typedef struct { /*@null@*/ void (*func)(void); } uzbl_cmdprop; -/* Functions */ -char * -itos(int val); - -gchar* -strfree(gchar *str); - -void -clean_up(void); - -void -catch_sigterm(int s); - -sigfunc * -setup_signal(int signe, sigfunc *shandler); - -gboolean -set_var_value(const gchar *name, gchar *val); - -void -load_uri_imp(gchar *uri); - -void -print(WebKitWebView *page, GArray *argv, GString *result); - -void -commands_hash(void); - -void -load_uri (WebKitWebView * web_view, GArray *argv, GString *result); - -void -chain (WebKitWebView *page, GArray *argv, GString *result); - -void -close_uzbl (WebKitWebView *page, GArray *argv, GString *result); - -gboolean -run_command(const gchar *command, const gchar **args, const gboolean sync, - char **output_stdout); - -void -spawn_async(WebKitWebView *web_view, GArray *argv, GString *result); - -void -spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result); - -void -spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result); - -void -spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result); - -void -spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result); - -void -parse_command(const char *cmd, const char *param, GString *result); - -void -parse_cmd_line(const char *ctl_line, GString *result); +/* Functions */ +char* itos(int val); +gchar* strfree(gchar *str); +void clean_up(void); + +/* Signal management functions */ +void catch_sigterm(int s); +sigfunc* setup_signal(int signe, sigfunc *shandler); + +gboolean set_var_value(const gchar *name, gchar *val); +void load_uri_imp(gchar *uri); +void print(WebKitWebView *page, GArray *argv, GString *result); +void commands_hash(void); +void load_uri(WebKitWebView * web_view, GArray *argv, GString *result); +void chain(WebKitWebView *page, GArray *argv, GString *result); +void close_uzbl(WebKitWebView *page, GArray *argv, GString *result); + +/* Running commands */ +gboolean run_command(const gchar *command, const gchar **args, const gboolean sync, + char **output_stdout); +void spawn_async(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sh_async(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sync(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sh_sync(WebKitWebView *web_view, GArray *argv, GString *result); +void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *result); +void parse_command(const char *cmd, const char *param, GString *result); +void parse_cmd_line(const char *ctl_line, GString *result); + +/* Communication functions */ /*@null@*/ gchar* build_stream_name(int type, const gchar *dir); -gboolean -control_fifo(GIOChannel *gio, GIOCondition condition); +gboolean control_fifo(GIOChannel *gio, GIOCondition condition); /*@null@*/ gchar* init_fifo(gchar *dir); -gboolean -control_stdin(GIOChannel *gio, GIOCondition condition); - -void -create_stdin(); +gboolean control_stdin(GIOChannel *gio, GIOCondition condition); +void create_stdin(); /*@null@*/ gchar* init_socket(gchar *dir); -gboolean -control_socket(GIOChannel *chan); - -gboolean -control_client_socket(GIOChannel *chan); - -void -update_title (void); +gboolean control_socket(GIOChannel *chan); +gboolean control_client_socket(GIOChannel *chan); -gboolean -key_press_cb (GtkWidget* window, GdkEventKey* event); -gboolean -key_release_cb (GtkWidget* window, GdkEventKey* event); +void update_title(void); -void -initialize (int argc, char *argv[]); +/* Keyboard events functions */ +gboolean key_press_cb(GtkWidget* window, GdkEventKey* event); +gboolean key_release_cb(GtkWidget* window, GdkEventKey* event); -void -create_browser (); +/* Initialization functions */ +void initialize(int argc, char *argv[]); +void create_browser(); +GtkWidget* create_mainbar(); +GtkWidget* create_window(); +GtkPlug* create_plug(); +void run_handler(const gchar *act, const gchar *args); +void settings_init(); -GtkWidget* -create_mainbar (); +/* Search functions */ +void search_text (WebKitWebView *page, GArray *argv, const gboolean forward); +void search_forward_text (WebKitWebView *page, GArray *argv, GString *result); +void search_reverse_text (WebKitWebView *page, GArray *argv, GString *result); +void search_clear(WebKitWebView *page, GArray *argv, GString *result); +void dehilight (WebKitWebView *page, GArray *argv, GString *result); -GtkWidget* -create_window (); +/* Javascript functions */ +void run_js (WebKitWebView * web_view, GArray *argv, GString *result); +void run_external_js (WebKitWebView * web_view, GArray *argv, GString *result); +void eval_js(WebKitWebView * web_view, gchar *script, GString *result, const gchar *script_file); -GtkPlug* -create_plug (); - -void -run_handler (const gchar *act, const gchar *args); - -void -settings_init (); - -void -search_text (WebKitWebView *page, GArray *argv, const gboolean forward); - -void -search_forward_text (WebKitWebView *page, GArray *argv, GString *result); - -void -search_reverse_text (WebKitWebView *page, GArray *argv, GString *result); - -void -search_clear(WebKitWebView *page, GArray *argv, GString *result); - -void -dehilight (WebKitWebView *page, GArray *argv, GString *result); - -void -run_js (WebKitWebView * web_view, GArray *argv, GString *result); - -void -run_external_js (WebKitWebView * web_view, GArray *argv, GString *result); - -void -eval_js(WebKitWebView * web_view, gchar *script, GString *result, const gchar *script_file); - -void -handle_authentication (SoupSession *session, +/* Network functions */ +void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data); - -void handle_cookies (SoupSession *session, +void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data); - -void -set_var(WebKitWebView *page, GArray *argv, GString *result); - -void -act_dump_config(); - -void -act_dump_config_as_events(); - -void -dump_var_hash(gpointer k, gpointer v, gpointer ud); - -void -dump_key_hash(gpointer k, gpointer v, gpointer ud); - -void -dump_config(); - -void -dump_config_as_events(); - -void -retrieve_geometry(); - -void -set_webview_scroll_adjustments(); - -void -event(WebKitWebView *page, GArray *argv, GString *result); - -void -init_connect_socket(); - -gboolean -remove_socket_from_array(GIOChannel *chan); - -void -menu_add(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_link(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_image(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_edit(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_separator(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_separator_link(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_separator_image(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_add_separator_edit(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_remove(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_remove_link(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_remove_image(WebKitWebView *page, GArray *argv, GString *result); - -void -menu_remove_edit(WebKitWebView *page, GArray *argv, GString *result); - -gint -get_click_context(); - -void -hardcopy(WebKitWebView *page, GArray *argv, GString *result); - -void -include(WebKitWebView *page, GArray *argv, GString *result); - -void -show_inspector(WebKitWebView *page, GArray *argv, GString *result); - -void -add_cookie(WebKitWebView *page, GArray *argv, GString *result); - -void -delete_cookie(WebKitWebView *page, GArray *argv, GString *result); - -void -builtins(); +void set_var(WebKitWebView *page, GArray *argv, GString *result); +void act_dump_config(); +void act_dump_config_as_events(); +void dump_var_hash(gpointer k, gpointer v, gpointer ud); +void dump_key_hash(gpointer k, gpointer v, gpointer ud); +void dump_config(); +void dump_config_as_events(); + +void retrieve_geometry(); +void set_webview_scroll_adjustments(); +void event(WebKitWebView *page, GArray *argv, GString *result); +void init_connect_socket(); +gboolean remove_socket_from_array(GIOChannel *chan); + +/* Contextual menu functions */ +void menu_add(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_link(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_image(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_edit(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator_link(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator_image(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator_edit(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove_link(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove_image(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove_edit(WebKitWebView *page, GArray *argv, GString *result); + +gint get_click_context(); +void hardcopy(WebKitWebView *page, GArray *argv, GString *result); +void include(WebKitWebView *page, GArray *argv, GString *result); +void show_inspector(WebKitWebView *page, GArray *argv, GString *result); +void add_cookie(WebKitWebView *page, GArray *argv, GString *result); +void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); +void builtins(); typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); typedef struct { - Command function; + Command function; gboolean no_split; } CommandInfo; typedef struct { - gchar *name; - gchar *cmd; + gchar* name; + gchar* cmd; gboolean issep; - guint context; + guint context; } MenuItem; -- cgit v1.2.3 From 7728278b675df32a1afc5531a57918df0d59f450 Mon Sep 17 00:00:00 2001 From: koral Date: Thu, 3 Feb 2011 09:54:42 +0100 Subject: Cleans and reorders initialization elements. --- src/uzbl-core.c | 112 ++++++++++++++++++++++++++++++++------------------------ src/uzbl-core.h | 4 +- 2 files changed, 66 insertions(+), 50 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 877dbda..3c6407e 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -40,8 +40,7 @@ UzblCore uzbl; /* commandline arguments (set initial values for the state variables) */ const -GOptionEntry entries[] = -{ +GOptionEntry entries[] = { { "uri", 'u', 0, G_OPTION_ARG_STRING, &uzbl.state.uri, "Uri to load at startup (equivalent to 'uzbl ' or 'set uri = URI' after uzbl has launched)", "URI" }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &uzbl.state.verbose, @@ -623,8 +622,7 @@ struct {const char *key; CommandInfo value;} cmdlist[] = }; void -commands_hash(void) -{ +commands_hash(void) { unsigned int i; uzbl.behave.commands = g_hash_table_new(g_str_hash, g_str_equal); @@ -1874,11 +1872,24 @@ update_title (void) { } } + void -create_browser () { - GUI *g = &uzbl.gui; +create_scrolled_win() { + GUI* g = &uzbl.gui; + + g->web_view = WEBKIT_WEB_VIEW(webkit_web_view_new()); + g->scrolled_win = gtk_scrolled_window_new(NULL, NULL); - g->web_view = WEBKIT_WEB_VIEW (webkit_web_view_new ()); + gtk_scrolled_window_set_policy( + GTK_SCROLLED_WINDOW(g->scrolled_win), + GTK_POLICY_NEVER, + GTK_POLICY_NEVER + ); + + gtk_container_add( + GTK_CONTAINER(g->scrolled_win), + GTK_WIDGET(g->web_view) + ); g_object_connect((GObject*)g->web_view, "signal::key-press-event", (GCallback)key_press_cb, NULL, @@ -1904,8 +1915,9 @@ create_browser () { NULL); } + GtkWidget* -create_mainbar () { +create_mainbar() { GUI *g = &uzbl.gui; g->mainbar = gtk_hbox_new (FALSE, 0); @@ -2262,62 +2274,78 @@ set_webview_scroll_adjustments() { NULL); } -/* set up gtk, gobject, variable defaults and other things that tests and other + +/* Set up gtk, gobject, variable defaults and other things that tests and other * external applications need to do anyhow */ void -initialize(int argc, char *argv[]) { +initialize(int argc, char** argv) { int i; - for(i=0; i Date: Thu, 3 Feb 2011 14:27:01 +0100 Subject: Cleans/comments uzbl-core.c. --- src/uzbl-core.c | 200 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 106 insertions(+), 94 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 3c6407e..a25cf14 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -186,20 +186,20 @@ return EXP_ERR; * recurse == 1: don't expand '@(command)@' * recurse == 2: don't expand '@@' */ -gchar * -expand(const char *s, guint recurse) { - uzbl_cmdprop *c; +gchar* +expand(const char* s, guint recurse) { + uzbl_cmdprop* c; enum exp_type etype; - char *end_simple_var = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; - char *ret = NULL; - char *vend = NULL; - GError *err = NULL; - gchar *cmd_stdout = NULL; - gchar *mycmd = NULL; - GString *buf = g_string_new(""); - GString *js_ret = g_string_new(""); - - while(s && *s) { + char* end_simple_var = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; + char* ret = NULL; + char* vend = NULL; + GError* err = NULL; + gchar* cmd_stdout = NULL; + gchar* mycmd = NULL; + GString* buf = g_string_new(""); + GString* js_ret = g_string_new(""); + + while (s && *s) { switch(*s) { case '\\': g_string_append_c(buf, *++s); @@ -630,11 +630,12 @@ commands_hash(void) { g_hash_table_insert(uzbl.behave.commands, (gpointer) cmdlist[i].key, &cmdlist[i].value); } + void builtins() { - unsigned int i, - len = LENGTH(cmdlist); - GString *command_list = g_string_new(""); + unsigned int i; + unsigned int len = LENGTH(cmdlist); + GString* command_list = g_string_new(""); for (i = 0; i < len; i++) { g_string_append(command_list, cmdlist[i].key); @@ -1335,37 +1336,37 @@ parse_command(const char *cmd, const char *param, GString *result) { GString *tmp = g_string_new(""); if ((c = g_hash_table_lookup(uzbl.behave.commands, cmd))) { - guint i; - gchar **par = split_quoted(param, TRUE); - GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); - - if (c->no_split) { /* don't split */ - sharg_append(a, param); - } else if (par) { - for (i = 0; i < g_strv_length(par); i++) - sharg_append(a, par[i]); - } + guint i; + gchar **par = split_quoted(param, TRUE); + GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); + + if (c->no_split) { /* don't split */ + sharg_append(a, param); + } else if (par) { + for (i = 0; i < g_strv_length(par); i++) + sharg_append(a, par[i]); + } - if (result == NULL) { - GString *result_print = g_string_new(""); + if (result == NULL) { + GString *result_print = g_string_new(""); - c->function(uzbl.gui.web_view, a, result_print); - if (result_print->len) - printf("%*s\n", (int)result_print->len, result_print->str); + c->function(uzbl.gui.web_view, a, result_print); + if (result_print->len) + printf("%*s\n", (int)result_print->len, result_print->str); - g_string_free(result_print, TRUE); - } else { - c->function(uzbl.gui.web_view, a, result); - } - g_strfreev (par); - g_array_free (a, TRUE); - - if(strcmp("set", cmd) && - strcmp("event", cmd) && - strcmp("request", cmd)) { - g_string_printf(tmp, "%s %s", cmd, param?param:""); - send_event(COMMAND_EXECUTED, tmp->str, NULL); - } + g_string_free(result_print, TRUE); + } else { + c->function(uzbl.gui.web_view, a, result); + } + g_strfreev (par); + g_array_free (a, TRUE); + + if(strcmp("set", cmd) && + strcmp("event", cmd) && + strcmp("request", cmd)) { + g_string_printf(tmp, "%s %s", cmd, param?param:""); + send_event(COMMAND_EXECUTED, tmp->str, NULL); + } } else { g_string_printf (tmp, "%s %s", cmd, param?param:""); @@ -1464,15 +1465,15 @@ set_var_value(const gchar *name, gchar *val) { } void -parse_cmd_line(const char *ctl_line, GString *result) { - size_t len=0; - gchar *ctlstrip = NULL; - gchar *exp_line = NULL; - gchar *work_string = NULL; +parse_cmd_line(const char* ctl_line, GString* result) { + size_t len = 0; + gchar* ctlstrip = NULL; + gchar* exp_line = NULL; + gchar* work_string = NULL; work_string = g_strdup(ctl_line); - /* strip trailing newline */ + /* Strip trailing newline */ len = strlen(ctl_line); if (work_string[len - 1] == '\n') ctlstrip = g_strndup(work_string, len - 1); @@ -1833,8 +1834,9 @@ init_socket(gchar *dir) { /* return dir or, on error, free dir and return NULL * return NULL; } + void -update_title (void) { +update_title(void) { Behaviour *b = &uzbl.behave; const gchar *title_format = b->title_format_long; @@ -1949,11 +1951,12 @@ create_mainbar() { GtkWidget* -create_window () { +create_window() { GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size (GTK_WINDOW (window), 800, 600); gtk_widget_set_name (window, "Uzbl browser"); + gtk_window_set_title(GTK_WINDOW(window), "Uzbl browser"); /* if the window has been made small, it shouldn't try to resize itself due * to a long statusbar. */ @@ -1968,8 +1971,9 @@ create_window () { return window; } + GtkPlug* -create_plug () { +create_plug() { GtkPlug* plug = GTK_PLUG (gtk_plug_new (uzbl.state.socket_id)); g_signal_connect (G_OBJECT (plug), "destroy", G_CALLBACK (destroy_cb), NULL); g_signal_connect (G_OBJECT (plug), "key-press-event", G_CALLBACK (key_press_cb), NULL); @@ -2100,10 +2104,11 @@ run_handler (const gchar *act, const gchar *args) { void settings_init () { - State *s = &uzbl.state; - Network *n = &uzbl.net; - - int i; + State* s = &uzbl.state; + Network* n = &uzbl.net; + int i; + + /* Load default config */ for (i = 0; default_config[i].command != NULL; i++) { parse_cmd_line(default_config[i].command, NULL); } @@ -2114,11 +2119,12 @@ settings_init () { } else if (!s->config_file) { - s->config_file = find_xdg_file (0, "/uzbl/config"); + s->config_file = find_xdg_file(0, "/uzbl/config"); } + /* Load config file, if any */ if (s->config_file) { - if(!for_each_line_in_file(s->config_file, parse_cmd_line_cb, NULL)) { + if (!for_each_line_in_file(s->config_file, parse_cmd_line_cb, NULL)) { gchar *tmp = g_strdup_printf("File %s can not be read.", s->config_file); send_event(COMMAND_ERROR, tmp, NULL); g_free(tmp); @@ -2127,17 +2133,17 @@ settings_init () { } else if (uzbl.state.verbose) printf ("No configuration file loaded.\n"); - if(s->connect_socket_names) + if (s->connect_socket_names) init_connect_socket(); g_signal_connect(n->soup_session, "authenticate", G_CALLBACK(handle_authentication), NULL); } -void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data) { +void handle_authentication (SoupSession *session, SoupMessage *msg, SoupAuth *auth, gboolean retrying, gpointer user_data) { (void) user_data; - if(uzbl.behave.authentication_handler && *uzbl.behave.authentication_handler != 0) { + if (uzbl.behave.authentication_handler && *uzbl.behave.authentication_handler != 0) { gchar *info, *host, *realm; gchar *p; @@ -2279,8 +2285,6 @@ set_webview_scroll_adjustments() { * external applications need to do anyhow */ void initialize(int argc, char** argv) { - int i; - /* Parse commandline arguments */ GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default"); g_option_context_add_main_entries (context, entries, NULL); @@ -2295,14 +2299,10 @@ initialize(int argc, char** argv) { } /* Embedded mode */ - for (i=0; i 1 && !uzbl.state.uri) uri_override = g_strdup(argv[1]); + gboolean verbose_override = uzbl.state.verbose; - settings_init (); + /* Read configuration file */ + settings_init(); + /* Update status bar */ if (!uzbl.behave.show_status) gtk_widget_hide(uzbl.gui.mainbar); else @@ -2480,6 +2476,7 @@ main (int argc, char* argv[]) { /* WebInspector */ set_up_inspector(); + /* Options overriding */ if (verbose_override > uzbl.state.verbose) uzbl.state.verbose = verbose_override; @@ -2488,7 +2485,22 @@ main (int argc, char* argv[]) { g_free(uri_override); } - gtk_main (); + /* Verbose feedback */ + if (uzbl.state.verbose) { + printf("Uzbl start location: %s\n", argv[0]); + if (uzbl.state.socket_id) + printf("plug_id %i\n", gtk_plug_get_id(uzbl.gui.plug)); + else + printf("window_id %i\n",(int) uzbl.xwin); + printf("pid %i\n", getpid ()); + printf("name: %s\n", uzbl.state.instance_name); + printf("commit: %s\n", uzbl.info.commit); + } + + + gtk_main(); + + /* Cleanup and exit*/ clean_up(); return EXIT_SUCCESS; -- cgit v1.2.3 From d08b19e722e263d0f4cf6454e55414014b97b235 Mon Sep 17 00:00:00 2001 From: koral Date: Thu, 10 Feb 2011 14:26:55 +0100 Subject: Moves some utility functions to util.c. --- src/util.c | 17 ++++++++++++++ src/util.h | 4 ++++ src/uzbl-core.c | 72 ++++++++++++++++++++++++--------------------------------- src/uzbl-core.h | 2 -- 4 files changed, 51 insertions(+), 44 deletions(-) diff --git a/src/util.c b/src/util.c index 458c04f..2da484f 100644 --- a/src/util.c +++ b/src/util.c @@ -110,4 +110,21 @@ for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void * } +char* +itos(int val) { + char tmp[20]; + snprintf(tmp, sizeof(tmp), "%i", val); + return g_strdup(tmp); +} + +gchar* +strfree(gchar *str) { + g_free(str); + return NULL; +} + +gchar* +argv_idx(const GArray *a, const guint idx) { + return g_array_index(a, gchar*, idx); +} diff --git a/src/util.h b/src/util.h index 06531bb..e2ecf73 100644 --- a/src/util.h +++ b/src/util.h @@ -1,4 +1,5 @@ #include +#include typedef struct { gchar* environmental; @@ -11,3 +12,6 @@ gchar* find_xdg_file(int xdg_type, const char* filename); gboolean file_exists(const char* filename); char* str_replace(const char* search, const char* replace, const char* string); gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); +char* itos(int val); +gchar* strfree(gchar *str); +gchar* argv_idx(const GArray*, const guint); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index a25cf14..fc757e7 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -350,22 +350,6 @@ expand(const char* s, guint recurse) { return g_string_free(buf, FALSE); } -char * -itos(int val) { - char tmp[20]; - - snprintf(tmp, sizeof(tmp), "%i", val); - return g_strdup(tmp); -} - -gchar* -strfree(gchar *str) { - g_free(str); - return NULL; -} - -gchar* -argv_idx(const GArray *a, const guint idx) { return g_array_index(a, gchar*, idx); } /* search a PATH style string for an existing file+path combination */ gchar* @@ -416,15 +400,16 @@ find_existing_file(gchar* path_list) { return NULL; } + void clean_up(void) { - if(uzbl.info.pid_str) { + if (uzbl.info.pid_str) { send_event(INSTANCE_EXIT, uzbl.info.pid_str, NULL); g_free(uzbl.info.pid_str); uzbl.info.pid_str = NULL; } - if(uzbl.state.executable_path) { + if (uzbl.state.executable_path) { g_free(uzbl.state.executable_path); uzbl.state.executable_path = NULL; } @@ -434,7 +419,7 @@ clean_up(void) { uzbl.behave.commands = NULL; } - if(uzbl.state.event_buffer) { + if (uzbl.state.event_buffer) { g_ptr_array_free(uzbl.state.event_buffer, TRUE); uzbl.state.event_buffer = NULL; } @@ -494,7 +479,7 @@ empty_event_buffer(int s) { /* scroll a bar in a given direction */ void -scroll (GtkAdjustment* bar, gchar *amount_str) { +scroll(GtkAdjustment* bar, gchar *amount_str) { gchar *end; gdouble max_value; @@ -972,7 +957,7 @@ act_dump_config_as_events() { } void -load_uri (WebKitWebView *web_view, GArray *argv, GString *result) { +load_uri(WebKitWebView *web_view, GArray *argv, GString *result) { (void) web_view; (void) result; set_var_value("uri", argv_idx(argv, 0)); } @@ -1127,19 +1112,19 @@ search_forward_text (WebKitWebView *page, GArray *argv, GString *result) { } void -search_reverse_text (WebKitWebView *page, GArray *argv, GString *result) { +search_reverse_text(WebKitWebView *page, GArray *argv, GString *result) { (void) result; search_text(page, argv, FALSE); } void -dehilight (WebKitWebView *page, GArray *argv, GString *result) { +dehilight(WebKitWebView *page, GArray *argv, GString *result) { (void) argv; (void) result; webkit_web_view_set_highlight_text_matches (page, FALSE); } void -chain (WebKitWebView *page, GArray *argv, GString *result) { +chain(WebKitWebView *page, GArray *argv, GString *result) { (void) page; (void) result; gchar *a = NULL; gchar **parts = NULL; @@ -2285,11 +2270,26 @@ set_webview_scroll_adjustments() { * external applications need to do anyhow */ void initialize(int argc, char** argv) { + /* Initialize variables */ + uzbl.state.socket_id = 0; + uzbl.state.plug_mode = FALSE; + + uzbl.state.executable_path = g_strdup(argv[0]); + uzbl.state.selected_url = NULL; + uzbl.state.searchtx = NULL; + + uzbl.info.webkit_major = webkit_major_version(); + uzbl.info.webkit_minor = webkit_minor_version(); + uzbl.info.webkit_micro = webkit_micro_version(); + uzbl.info.arch = ARCH; + uzbl.info.commit = COMMIT; + + /* Parse commandline arguments */ GOptionContext* context = g_option_context_new ("[ uri ] - load a uri by default"); - g_option_context_add_main_entries (context, entries, NULL); - g_option_context_add_group (context, gtk_get_option_group (TRUE)); - g_option_context_parse (context, &argc, &argv, NULL); + g_option_context_add_main_entries(context, entries, NULL); + g_option_context_add_group(context, gtk_get_option_group (TRUE)); + g_option_context_parse(context, &argc, &argv, NULL); g_option_context_free(context); /* Only print version */ @@ -2303,7 +2303,7 @@ initialize(int argc, char** argv) { uzbl.state.plug_mode = TRUE; if (!g_thread_supported()) - g_thread_init (NULL); + g_thread_init(NULL); /* TODO: move the handler setup to event_buffer_timeout and disarm the @@ -2312,17 +2312,6 @@ initialize(int argc, char** argv) { fprintf(stderr, "uzbl: error hooking %d: %s\n", SIGALRM, strerror(errno)); event_buffer_timeout(10); - /* State information */ - uzbl.state.executable_path = g_strdup(argv[0]); - uzbl.state.selected_url = NULL; - uzbl.state.searchtx = NULL; - - /* Static information */ - uzbl.info.webkit_major = webkit_major_version(); - uzbl.info.webkit_minor = webkit_minor_version(); - uzbl.info.webkit_micro = webkit_micro_version(); - uzbl.info.arch = ARCH; - uzbl.info.commit = COMMIT; /* HTTP client */ uzbl.net.soup_session = webkit_get_default_session(); @@ -2340,9 +2329,8 @@ initialize(int argc, char** argv) { create_scrolled_win(); uzbl.gui.vbox = gtk_vbox_new(FALSE, 0); - - gtk_box_pack_start (GTK_BOX(uzbl.gui.vbox), uzbl.gui.scrolled_win, TRUE, TRUE, 0); - gtk_box_pack_start (GTK_BOX(uzbl.gui.vbox), uzbl.gui.mainbar, FALSE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(uzbl.gui.vbox), uzbl.gui.scrolled_win, TRUE, TRUE, 0); + gtk_box_pack_start(GTK_BOX(uzbl.gui.vbox), uzbl.gui.mainbar, FALSE, TRUE, 0); } diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 2ee3ddc..3e2f4a3 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -250,8 +250,6 @@ typedef struct { /* Functions */ -char* itos(int val); -gchar* strfree(gchar *str); void clean_up(void); /* Signal management functions */ -- cgit v1.2.3 From aa565b52f9f82b6c137b2af2178d7ffb9297f310 Mon Sep 17 00:00:00 2001 From: koral Date: Thu, 10 Feb 2011 14:39:15 +0100 Subject: Moves menu functions in a dedicated source file. --- src/menu.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/menu.h | 18 ++++++ src/uzbl-core.c | 173 +------------------------------------------------- src/uzbl-core.h | 19 ++---- 4 files changed, 215 insertions(+), 187 deletions(-) create mode 100644 src/menu.c create mode 100644 src/menu.h diff --git a/src/menu.c b/src/menu.c new file mode 100644 index 0000000..451b35a --- /dev/null +++ b/src/menu.c @@ -0,0 +1,192 @@ +#include "menu.h" +#include "util.h" +#include "uzbl-core.h" + +void +add_to_menu(GArray *argv, guint context) { + GUI *g = &uzbl.gui; + MenuItem *m; + gchar *item_cmd = NULL; + + if(!argv_idx(argv, 0)) + return; + + gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2); + if(!g->menu_items) + g->menu_items = g_ptr_array_new(); + + if(split[1]) + item_cmd = split[1]; + + if(split[0]) { + m = malloc(sizeof(MenuItem)); + m->name = g_strdup(split[0]); + m->cmd = g_strdup(item_cmd?item_cmd:""); + m->context = context; + m->issep = FALSE; + g_ptr_array_add(g->menu_items, m); + } + + g_strfreev(split); +} + + +void +menu_add(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT); + +} + + +void +menu_add_link(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK); +} + + +void +menu_add_image(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE); +} + + +void +menu_add_edit(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE); +} + + +void +add_separator_to_menu(GArray *argv, guint context) { + GUI *g = &uzbl.gui; + MenuItem *m; + gchar *sep_name; + + if(!g->menu_items) + g->menu_items = g_ptr_array_new(); + + if(!argv_idx(argv, 0)) + return; + else + sep_name = argv_idx(argv, 0); + + m = malloc(sizeof(MenuItem)); + m->name = g_strdup(sep_name); + m->cmd = NULL; + m->context = context; + m->issep = TRUE; + g_ptr_array_add(g->menu_items, m); +} + + +void +menu_add_separator(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT); +} + + +void +menu_add_separator_link(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK); +} + + +void +menu_add_separator_image(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE); +} + + +void +menu_add_separator_edit(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE); +} + + +void +remove_from_menu(GArray *argv, guint context) { + GUI *g = &uzbl.gui; + MenuItem *mi; + gchar *name = NULL; + guint i=0; + + if(!g->menu_items) + return; + + if(!argv_idx(argv, 0)) + return; + else + name = argv_idx(argv, 0); + + for(i=0; i < g->menu_items->len; i++) { + mi = g_ptr_array_index(g->menu_items, i); + + if((context == mi->context) && !strcmp(name, mi->name)) { + g_free(mi->name); + g_free(mi->cmd); + g_free(mi); + g_ptr_array_remove_index(g->menu_items, i); + } + } +} + + +void +menu_remove(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT); +} + + +void +menu_remove_link(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK); +} + + +void +menu_remove_image(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE); +} + + +void +menu_remove_edit(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; + (void) result; + + remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE); +} + diff --git a/src/menu.h b/src/menu.h new file mode 100644 index 0000000..8b89f2f --- /dev/null +++ b/src/menu.h @@ -0,0 +1,18 @@ +#ifndef __MENU__ +#define __MENU__ + +#include + +void menu_add(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_link(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_image(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_edit(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator_link(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator_image(WebKitWebView *page, GArray *argv, GString *result); +void menu_add_separator_edit(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove_link(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove_image(WebKitWebView *page, GArray *argv, GString *result); +void menu_remove_edit(WebKitWebView *page, GArray *argv, GString *result); +#endif diff --git a/src/uzbl-core.c b/src/uzbl-core.c index fc757e7..b83e13f 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -35,6 +35,7 @@ #include "inspector.h" #include "config.h" #include "util.h" +#include "menu.h" UzblCore uzbl; @@ -648,178 +649,6 @@ set_var(WebKitWebView *page, GArray *argv, GString *result) { g_strfreev(split); } -void -add_to_menu(GArray *argv, guint context) { - GUI *g = &uzbl.gui; - MenuItem *m; - gchar *item_cmd = NULL; - - if(!argv_idx(argv, 0)) - return; - - gchar **split = g_strsplit(argv_idx(argv, 0), "=", 2); - if(!g->menu_items) - g->menu_items = g_ptr_array_new(); - - if(split[1]) - item_cmd = split[1]; - - if(split[0]) { - m = malloc(sizeof(MenuItem)); - m->name = g_strdup(split[0]); - m->cmd = g_strdup(item_cmd?item_cmd:""); - m->context = context; - m->issep = FALSE; - g_ptr_array_add(g->menu_items, m); - } - - g_strfreev(split); -} - -void -menu_add(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT); - -} - -void -menu_add_link(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK); -} - -void -menu_add_image(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE); -} - -void -menu_add_edit(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE); -} - -void -add_separator_to_menu(GArray *argv, guint context) { - GUI *g = &uzbl.gui; - MenuItem *m; - gchar *sep_name; - - if(!g->menu_items) - g->menu_items = g_ptr_array_new(); - - if(!argv_idx(argv, 0)) - return; - else - sep_name = argv_idx(argv, 0); - - m = malloc(sizeof(MenuItem)); - m->name = g_strdup(sep_name); - m->cmd = NULL; - m->context = context; - m->issep = TRUE; - g_ptr_array_add(g->menu_items, m); -} - -void -menu_add_separator(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT); -} - -void -menu_add_separator_link(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK); -} -void -menu_add_separator_image(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE); -} - -void -menu_add_separator_edit(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - add_separator_to_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE); -} - -void -remove_from_menu(GArray *argv, guint context) { - GUI *g = &uzbl.gui; - MenuItem *mi; - gchar *name = NULL; - guint i=0; - - if(!g->menu_items) - return; - - if(!argv_idx(argv, 0)) - return; - else - name = argv_idx(argv, 0); - - for(i=0; i < g->menu_items->len; i++) { - mi = g_ptr_array_index(g->menu_items, i); - - if((context == mi->context) && !strcmp(name, mi->name)) { - g_free(mi->name); - g_free(mi->cmd); - g_free(mi); - g_ptr_array_remove_index(g->menu_items, i); - } - } -} - -void -menu_remove(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT); -} - -void -menu_remove_link(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_LINK); -} - -void -menu_remove_image(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE); -} - -void -menu_remove_edit(WebKitWebView *page, GArray *argv, GString *result) { - (void) page; - (void) result; - - remove_from_menu(argv, WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE); -} void event(WebKitWebView *page, GArray *argv, GString *result) { diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 3e2f4a3..e1e24eb 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -10,6 +10,9 @@ * */ +#ifndef __UZBL_CORE__ +#define __UZBL_CORE__ + #define _POSIX_SOURCE #include @@ -344,20 +347,6 @@ void event(WebKitWebView *page, GArray *argv, GString *result); void init_connect_socket(); gboolean remove_socket_from_array(GIOChannel *chan); -/* Contextual menu functions */ -void menu_add(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_link(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_image(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_edit(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_separator(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_separator_link(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_separator_image(WebKitWebView *page, GArray *argv, GString *result); -void menu_add_separator_edit(WebKitWebView *page, GArray *argv, GString *result); -void menu_remove(WebKitWebView *page, GArray *argv, GString *result); -void menu_remove_link(WebKitWebView *page, GArray *argv, GString *result); -void menu_remove_image(WebKitWebView *page, GArray *argv, GString *result); -void menu_remove_edit(WebKitWebView *page, GArray *argv, GString *result); - gint get_click_context(); void hardcopy(WebKitWebView *page, GArray *argv, GString *result); void include(WebKitWebView *page, GArray *argv, GString *result); @@ -380,5 +369,5 @@ typedef struct { guint context; } MenuItem; - +#endif /* vi: set et ts=4: */ -- cgit v1.2.3 From ece7f8a0bc6f4b45e931ce2634f79fe6c84a18c9 Mon Sep 17 00:00:00 2001 From: koral Date: Thu, 10 Feb 2011 14:57:01 +0100 Subject: Moves I/O functions to a dedicated source file. --- src/callbacks.c | 1 + src/events.h | 7 ++ src/io.c | 347 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/io.h | 23 ++++ src/uzbl-core.c | 333 +---------------------------------------------------- src/uzbl-core.h | 18 --- 6 files changed, 379 insertions(+), 350 deletions(-) create mode 100644 src/io.c create mode 100644 src/io.h diff --git a/src/callbacks.c b/src/callbacks.c index b947c8e..2ba4e6c 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -7,6 +7,7 @@ #include "callbacks.h" #include "events.h" #include "util.h" +#include "io.h" void diff --git a/src/events.h b/src/events.h index 3c7b933..4edc5ab 100644 --- a/src/events.h +++ b/src/events.h @@ -3,6 +3,11 @@ ** (c) 2009 by Robert Manea */ +#ifndef __EVENTS__ +#define __EVENTS__ + +#include + /* Event system */ enum event_type { LOAD_START, LOAD_COMMIT, LOAD_FINISH, LOAD_ERROR, @@ -37,3 +42,5 @@ send_event(int type, const gchar *details, const gchar *custom_event); void key_to_event(guint keyval, gint mode); + +#endif diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..80dd666 --- /dev/null +++ b/src/io.c @@ -0,0 +1,347 @@ +#include + +#include "events.h" +#include "io.h" +#include "util.h" +#include "uzbl-core.h" + +/*@null@*/ gchar* +build_stream_name(int type, const gchar* dir) { + State *s = &uzbl.state; + gchar *str = NULL; + + if (type == FIFO) { + str = g_strdup_printf + ("%s/uzbl_fifo_%s", dir, s->instance_name); + } else if (type == SOCKET) { + str = g_strdup_printf + ("%s/uzbl_socket_%s", dir, s->instance_name); + } + return str; +} + + +gboolean +control_fifo(GIOChannel *gio, GIOCondition condition) { + if (uzbl.state.verbose) + printf("triggered\n"); + gchar *ctl_line; + GIOStatus ret; + GError *err = NULL; + + if (condition & G_IO_HUP) + g_error ("Fifo: Read end of pipe died!\n"); + + if(!gio) + g_error ("Fifo: GIOChannel broke\n"); + + ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, &err); + if (ret == G_IO_STATUS_ERROR) { + g_error ("Fifo: Error reading: %s\n", err->message); + g_error_free (err); + } + + parse_cmd_line(ctl_line, NULL); + g_free(ctl_line); + + return TRUE; +} + + +gboolean +attach_fifo(gchar *path) { + GError *error = NULL; + /* 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. */ + GIOChannel *chan = g_io_channel_new_file(path, "r+", &error); + if (chan) { + if (g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, NULL)) { + if (uzbl.state.verbose) + printf ("attach_fifo: created successfully as %s\n", path); + send_event(FIFO_SET, path, NULL); + uzbl.comm.fifo_path = path; + g_setenv("UZBL_FIFO", uzbl.comm.fifo_path, TRUE); + return TRUE; + } else g_warning ("attach_fifo: could not add watch on %s\n", path); + } else g_warning ("attach_fifo: can't open: %s\n", error->message); + + if (error) g_error_free (error); + return FALSE; +} + + +/*@null@*/ gchar* +init_fifo(gchar *dir) { /* return dir or, on error, free dir and return NULL */ + if (uzbl.comm.fifo_path) { /* get rid of the old fifo if one exists */ + if (unlink(uzbl.comm.fifo_path) == -1) + g_warning ("Fifo: Can't unlink old fifo at %s\n", uzbl.comm.fifo_path); + g_free(uzbl.comm.fifo_path); + uzbl.comm.fifo_path = NULL; + } + + gchar *path = build_stream_name(FIFO, dir); + + if (!file_exists(path)) { + if (mkfifo (path, 0666) == 0 && attach_fifo(path)) { + return dir; + } else g_warning ("init_fifo: can't create %s: %s\n", path, strerror(errno)); + } else { + /* the fifo exists. but is anybody home? */ + int fd = open(path, O_WRONLY|O_NONBLOCK); + if(fd < 0) { + /* some error occurred, presumably nobody's on the read end. + * we can attach ourselves to it. */ + if(attach_fifo(path)) + return dir; + else + g_warning("init_fifo: can't attach to %s: %s\n", path, strerror(errno)); + } else { + /* somebody's there, we can't use that fifo. */ + close(fd); + /* whatever, this instance can live without a fifo. */ + g_warning ("init_fifo: can't create %s: file exists and is occupied\n", path); + } + } + + /* if we got this far, there was an error; cleanup */ + g_free(dir); + g_free(path); + return NULL; +} + + +gboolean +control_stdin(GIOChannel *gio, GIOCondition condition) { + (void) condition; + gchar *ctl_line = NULL; + GIOStatus ret; + + ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, NULL); + if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) ) + return FALSE; + + parse_cmd_line(ctl_line, NULL); + g_free(ctl_line); + + return TRUE; +} + + +void +create_stdin () { + GIOChannel *chan = NULL; + GError *error = NULL; + + chan = g_io_channel_unix_new(fileno(stdin)); + if (chan) { + if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) { + g_error ("Stdin: could not add watch\n"); + } else { + if (uzbl.state.verbose) + printf ("Stdin: watch added successfully\n"); + } + } else { + g_error ("Stdin: Error while opening: %s\n", error->message); + } + if (error) g_error_free (error); +} + + +gboolean +remove_socket_from_array(GIOChannel *chan) { + gboolean ret = 0; + + ret = g_ptr_array_remove_fast(uzbl.comm.connect_chan, chan); + if(!ret) + ret = g_ptr_array_remove_fast(uzbl.comm.client_chan, chan); + + if(ret) + g_io_channel_unref (chan); + return ret; +} + + +gboolean +control_socket(GIOChannel *chan) { + struct sockaddr_un remote; + unsigned int t = sizeof(remote); + GIOChannel *iochan; + int clientsock; + + clientsock = accept (g_io_channel_unix_get_fd(chan), + (struct sockaddr *) &remote, &t); + + if(!uzbl.comm.client_chan) + uzbl.comm.client_chan = g_ptr_array_new(); + + if ((iochan = g_io_channel_unix_new(clientsock))) { + g_io_channel_set_encoding(iochan, NULL, NULL); + g_io_add_watch(iochan, G_IO_IN|G_IO_HUP, + (GIOFunc) control_client_socket, iochan); + g_ptr_array_add(uzbl.comm.client_chan, (gpointer)iochan); + } + return TRUE; +} + + +void +init_connect_socket() { + int sockfd, replay = 0; + struct sockaddr_un local; + GIOChannel *chan; + gchar **name = NULL; + + if(!uzbl.comm.connect_chan) + uzbl.comm.connect_chan = g_ptr_array_new(); + + name = uzbl.state.connect_socket_names; + + while(name && *name) { + sockfd = socket (AF_UNIX, SOCK_STREAM, 0); + local.sun_family = AF_UNIX; + strcpy (local.sun_path, *name); + + if(!connect(sockfd, (struct sockaddr *) &local, sizeof(local))) { + if ((chan = g_io_channel_unix_new(sockfd))) { + g_io_channel_set_encoding(chan, NULL, NULL); + g_io_add_watch(chan, G_IO_IN|G_IO_HUP, + (GIOFunc) control_client_socket, chan); + g_ptr_array_add(uzbl.comm.connect_chan, (gpointer)chan); + replay++; + } + } + else + g_warning("Error connecting to socket: %s\n", *name); + name++; + } + + /* replay buffered events */ + if(replay) + send_event_socket(NULL); +} + + +gboolean +control_client_socket(GIOChannel *clientchan) { + char *ctl_line; + GString *result = g_string_new(""); + GError *error = NULL; + GIOStatus ret; + gsize len; + + ret = g_io_channel_read_line(clientchan, &ctl_line, &len, NULL, &error); + if (ret == G_IO_STATUS_ERROR) { + g_warning ("Error reading: %s", error->message); + g_clear_error (&error); + ret = g_io_channel_shutdown (clientchan, TRUE, &error); + remove_socket_from_array (clientchan); + if (ret == G_IO_STATUS_ERROR) { + g_warning ("Error closing: %s", error->message); + g_clear_error (&error); + } + return FALSE; + } else if (ret == G_IO_STATUS_EOF) { + /* shutdown and remove channel watch from main loop */ + ret = g_io_channel_shutdown (clientchan, TRUE, &error); + remove_socket_from_array (clientchan); + if (ret == G_IO_STATUS_ERROR) { + g_warning ("Error closing: %s", error->message); + g_clear_error (&error); + } + return FALSE; + } + + if (ctl_line) { + parse_cmd_line (ctl_line, result); + g_string_append_c(result, '\n'); + ret = g_io_channel_write_chars (clientchan, result->str, result->len, + &len, &error); + if (ret == G_IO_STATUS_ERROR) { + g_warning ("Error writing: %s", error->message); + g_clear_error (&error); + } + if (g_io_channel_flush(clientchan, &error) == G_IO_STATUS_ERROR) { + g_warning ("Error flushing: %s", error->message); + g_clear_error (&error); + } + } + + g_string_free(result, TRUE); + g_free(ctl_line); + return TRUE; +} + + +gboolean +attach_socket(gchar *path, struct sockaddr_un *local) { + GIOChannel *chan = NULL; + int sock = socket (AF_UNIX, SOCK_STREAM, 0); + + if (bind (sock, (struct sockaddr *) local, sizeof(*local)) != -1) { + if (uzbl.state.verbose) + printf ("init_socket: opened in %s\n", path); + + if(listen (sock, 5) < 0) + g_warning ("attach_socket: could not listen on %s: %s\n", path, strerror(errno)); + + if( (chan = g_io_channel_unix_new(sock)) ) { + g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_socket, chan); + uzbl.comm.socket_path = path; + send_event(SOCKET_SET, path, NULL); + g_setenv("UZBL_SOCKET", uzbl.comm.socket_path, TRUE); + return TRUE; + } + } else g_warning ("attach_socket: could not bind to %s: %s\n", path, strerror(errno)); + + return FALSE; +} + + +/*@null@*/ gchar* +init_socket(gchar *dir) { /* return dir or, on error, free dir and return NULL */ + if (uzbl.comm.socket_path) { /* remove an existing socket should one exist */ + if (unlink(uzbl.comm.socket_path) == -1) + g_warning ("init_socket: couldn't unlink socket at %s\n", uzbl.comm.socket_path); + g_free(uzbl.comm.socket_path); + uzbl.comm.socket_path = NULL; + } + + if (*dir == ' ') { + g_free(dir); + return NULL; + } + + struct sockaddr_un local; + gchar *path = build_stream_name(SOCKET, dir); + + local.sun_family = AF_UNIX; + strcpy (local.sun_path, path); + + if(!file_exists(path) && attach_socket(path, &local)) { + /* it's free for the taking. */ + return dir; + } else { + /* see if anybody's listening on the socket path we want. */ + int sock = socket (AF_UNIX, SOCK_STREAM, 0); + if(connect(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { + /* some error occurred, presumably nobody's listening. + * we can attach ourselves to it. */ + unlink(path); + if(attach_socket(path, &local)) + return dir; + else + g_warning("init_socket: can't attach to existing socket %s: %s\n", path, strerror(errno)); + } else { + /* somebody's there, we can't use that socket path. */ + close(sock); + /* whatever, this instance can live without a socket. */ + g_warning ("init_socket: can't create %s: socket exists and is occupied\n", path); + } + } + + /* if we got this far, there was an error; cleanup */ + g_free(path); + g_free(dir); + return NULL; +} diff --git a/src/io.h b/src/io.h new file mode 100644 index 0000000..a6ea0a1 --- /dev/null +++ b/src/io.h @@ -0,0 +1,23 @@ +#ifndef __IO__ +#define __IO__ + +#include + +/*@null@*/ gchar* +build_stream_name(int type, const gchar *dir); + +gboolean control_fifo(GIOChannel *gio, GIOCondition condition); + +/*@null@*/ gchar* +init_fifo(gchar *dir); + +gboolean control_stdin(GIOChannel *gio, GIOCondition condition); +void create_stdin(); + +/*@null@*/ gchar* +init_socket(gchar *dir); + +gboolean control_socket(GIOChannel *chan); +gboolean control_client_socket(GIOChannel *chan); + +#endif diff --git a/src/uzbl-core.c b/src/uzbl-core.c index b83e13f..8cc20bb 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -36,6 +36,7 @@ #include "config.h" #include "util.h" #include "menu.h" +#include "io.h" UzblCore uzbl; @@ -1316,338 +1317,6 @@ parse_cmd_line(const char* ctl_line, GString* result) { g_free(ctlstrip); } -/*@null@*/ gchar* -build_stream_name(int type, const gchar* dir) { - State *s = &uzbl.state; - gchar *str = NULL; - - if (type == FIFO) { - str = g_strdup_printf - ("%s/uzbl_fifo_%s", dir, s->instance_name); - } else if (type == SOCKET) { - str = g_strdup_printf - ("%s/uzbl_socket_%s", dir, s->instance_name); - } - return str; -} - -gboolean -control_fifo(GIOChannel *gio, GIOCondition condition) { - if (uzbl.state.verbose) - printf("triggered\n"); - gchar *ctl_line; - GIOStatus ret; - GError *err = NULL; - - if (condition & G_IO_HUP) - g_error ("Fifo: Read end of pipe died!\n"); - - if(!gio) - g_error ("Fifo: GIOChannel broke\n"); - - ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, &err); - if (ret == G_IO_STATUS_ERROR) { - g_error ("Fifo: Error reading: %s\n", err->message); - g_error_free (err); - } - - parse_cmd_line(ctl_line, NULL); - g_free(ctl_line); - - return TRUE; -} - -gboolean -attach_fifo(gchar *path) { - GError *error = NULL; - /* 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. */ - GIOChannel *chan = g_io_channel_new_file(path, "r+", &error); - if (chan) { - if (g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, NULL)) { - if (uzbl.state.verbose) - printf ("attach_fifo: created successfully as %s\n", path); - send_event(FIFO_SET, path, NULL); - uzbl.comm.fifo_path = path; - g_setenv("UZBL_FIFO", uzbl.comm.fifo_path, TRUE); - return TRUE; - } else g_warning ("attach_fifo: could not add watch on %s\n", path); - } else g_warning ("attach_fifo: can't open: %s\n", error->message); - - if (error) g_error_free (error); - return FALSE; -} - -/*@null@*/ gchar* -init_fifo(gchar *dir) { /* return dir or, on error, free dir and return NULL */ - if (uzbl.comm.fifo_path) { /* get rid of the old fifo if one exists */ - if (unlink(uzbl.comm.fifo_path) == -1) - g_warning ("Fifo: Can't unlink old fifo at %s\n", uzbl.comm.fifo_path); - g_free(uzbl.comm.fifo_path); - uzbl.comm.fifo_path = NULL; - } - - gchar *path = build_stream_name(FIFO, dir); - - if (!file_exists(path)) { - if (mkfifo (path, 0666) == 0 && attach_fifo(path)) { - return dir; - } else g_warning ("init_fifo: can't create %s: %s\n", path, strerror(errno)); - } else { - /* the fifo exists. but is anybody home? */ - int fd = open(path, O_WRONLY|O_NONBLOCK); - if(fd < 0) { - /* some error occurred, presumably nobody's on the read end. - * we can attach ourselves to it. */ - if(attach_fifo(path)) - return dir; - else - g_warning("init_fifo: can't attach to %s: %s\n", path, strerror(errno)); - } else { - /* somebody's there, we can't use that fifo. */ - close(fd); - /* whatever, this instance can live without a fifo. */ - g_warning ("init_fifo: can't create %s: file exists and is occupied\n", path); - } - } - - /* if we got this far, there was an error; cleanup */ - g_free(dir); - g_free(path); - return NULL; -} - -gboolean -control_stdin(GIOChannel *gio, GIOCondition condition) { - (void) condition; - gchar *ctl_line = NULL; - GIOStatus ret; - - ret = g_io_channel_read_line(gio, &ctl_line, NULL, NULL, NULL); - if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) ) - return FALSE; - - parse_cmd_line(ctl_line, NULL); - g_free(ctl_line); - - return TRUE; -} - -void -create_stdin () { - GIOChannel *chan = NULL; - GError *error = NULL; - - chan = g_io_channel_unix_new(fileno(stdin)); - if (chan) { - if (!g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_stdin, NULL)) { - g_error ("Stdin: could not add watch\n"); - } else { - if (uzbl.state.verbose) - printf ("Stdin: watch added successfully\n"); - } - } else { - g_error ("Stdin: Error while opening: %s\n", error->message); - } - if (error) g_error_free (error); -} - -gboolean -remove_socket_from_array(GIOChannel *chan) { - gboolean ret = 0; - - ret = g_ptr_array_remove_fast(uzbl.comm.connect_chan, chan); - if(!ret) - ret = g_ptr_array_remove_fast(uzbl.comm.client_chan, chan); - - if(ret) - g_io_channel_unref (chan); - return ret; -} - -gboolean -control_socket(GIOChannel *chan) { - struct sockaddr_un remote; - unsigned int t = sizeof(remote); - GIOChannel *iochan; - int clientsock; - - clientsock = accept (g_io_channel_unix_get_fd(chan), - (struct sockaddr *) &remote, &t); - - if(!uzbl.comm.client_chan) - uzbl.comm.client_chan = g_ptr_array_new(); - - if ((iochan = g_io_channel_unix_new(clientsock))) { - g_io_channel_set_encoding(iochan, NULL, NULL); - g_io_add_watch(iochan, G_IO_IN|G_IO_HUP, - (GIOFunc) control_client_socket, iochan); - g_ptr_array_add(uzbl.comm.client_chan, (gpointer)iochan); - } - return TRUE; -} - -void -init_connect_socket() { - int sockfd, replay = 0; - struct sockaddr_un local; - GIOChannel *chan; - gchar **name = NULL; - - if(!uzbl.comm.connect_chan) - uzbl.comm.connect_chan = g_ptr_array_new(); - - name = uzbl.state.connect_socket_names; - - while(name && *name) { - sockfd = socket (AF_UNIX, SOCK_STREAM, 0); - local.sun_family = AF_UNIX; - strcpy (local.sun_path, *name); - - if(!connect(sockfd, (struct sockaddr *) &local, sizeof(local))) { - if ((chan = g_io_channel_unix_new(sockfd))) { - g_io_channel_set_encoding(chan, NULL, NULL); - g_io_add_watch(chan, G_IO_IN|G_IO_HUP, - (GIOFunc) control_client_socket, chan); - g_ptr_array_add(uzbl.comm.connect_chan, (gpointer)chan); - replay++; - } - } - else - g_warning("Error connecting to socket: %s\n", *name); - name++; - } - - /* replay buffered events */ - if(replay) - send_event_socket(NULL); -} - -gboolean -control_client_socket(GIOChannel *clientchan) { - char *ctl_line; - GString *result = g_string_new(""); - GError *error = NULL; - GIOStatus ret; - gsize len; - - ret = g_io_channel_read_line(clientchan, &ctl_line, &len, NULL, &error); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error reading: %s", error->message); - g_clear_error (&error); - ret = g_io_channel_shutdown (clientchan, TRUE, &error); - remove_socket_from_array (clientchan); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error closing: %s", error->message); - g_clear_error (&error); - } - return FALSE; - } else if (ret == G_IO_STATUS_EOF) { - /* shutdown and remove channel watch from main loop */ - ret = g_io_channel_shutdown (clientchan, TRUE, &error); - remove_socket_from_array (clientchan); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error closing: %s", error->message); - g_clear_error (&error); - } - return FALSE; - } - - if (ctl_line) { - parse_cmd_line (ctl_line, result); - g_string_append_c(result, '\n'); - ret = g_io_channel_write_chars (clientchan, result->str, result->len, - &len, &error); - if (ret == G_IO_STATUS_ERROR) { - g_warning ("Error writing: %s", error->message); - g_clear_error (&error); - } - if (g_io_channel_flush(clientchan, &error) == G_IO_STATUS_ERROR) { - g_warning ("Error flushing: %s", error->message); - g_clear_error (&error); - } - } - - g_string_free(result, TRUE); - g_free(ctl_line); - return TRUE; -} - - -gboolean -attach_socket(gchar *path, struct sockaddr_un *local) { - GIOChannel *chan = NULL; - int sock = socket (AF_UNIX, SOCK_STREAM, 0); - - if (bind (sock, (struct sockaddr *) local, sizeof(*local)) != -1) { - if (uzbl.state.verbose) - printf ("init_socket: opened in %s\n", path); - - if(listen (sock, 5) < 0) - g_warning ("attach_socket: could not listen on %s: %s\n", path, strerror(errno)); - - if( (chan = g_io_channel_unix_new(sock)) ) { - g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_socket, chan); - uzbl.comm.socket_path = path; - send_event(SOCKET_SET, path, NULL); - g_setenv("UZBL_SOCKET", uzbl.comm.socket_path, TRUE); - return TRUE; - } - } else g_warning ("attach_socket: could not bind to %s: %s\n", path, strerror(errno)); - - return FALSE; -} - - -/*@null@*/ gchar* -init_socket(gchar *dir) { /* return dir or, on error, free dir and return NULL */ - if (uzbl.comm.socket_path) { /* remove an existing socket should one exist */ - if (unlink(uzbl.comm.socket_path) == -1) - g_warning ("init_socket: couldn't unlink socket at %s\n", uzbl.comm.socket_path); - g_free(uzbl.comm.socket_path); - uzbl.comm.socket_path = NULL; - } - - if (*dir == ' ') { - g_free(dir); - return NULL; - } - - struct sockaddr_un local; - gchar *path = build_stream_name(SOCKET, dir); - - local.sun_family = AF_UNIX; - strcpy (local.sun_path, path); - - if(!file_exists(path) && attach_socket(path, &local)) { - /* it's free for the taking. */ - return dir; - } else { - /* see if anybody's listening on the socket path we want. */ - int sock = socket (AF_UNIX, SOCK_STREAM, 0); - if(connect(sock, (struct sockaddr *) &local, sizeof(local)) < 0) { - /* some error occurred, presumably nobody's listening. - * we can attach ourselves to it. */ - unlink(path); - if(attach_socket(path, &local)) - return dir; - else - g_warning("init_socket: can't attach to existing socket %s: %s\n", path, strerror(errno)); - } else { - /* somebody's there, we can't use that socket path. */ - close(sock); - /* whatever, this instance can live without a socket. */ - g_warning ("init_socket: can't create %s: socket exists and is occupied\n", path); - } - } - - /* if we got this far, there was an error; cleanup */ - g_free(path); - g_free(dir); - return NULL; -} - void update_title(void) { diff --git a/src/uzbl-core.h b/src/uzbl-core.h index e1e24eb..76421d2 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -278,24 +278,6 @@ void spawn_sync_exec(WebKitWebView *web_view, GArray *argv, GString *resu void parse_command(const char *cmd, const char *param, GString *result); void parse_cmd_line(const char *ctl_line, GString *result); -/* Communication functions */ -/*@null@*/ gchar* -build_stream_name(int type, const gchar *dir); - -gboolean control_fifo(GIOChannel *gio, GIOCondition condition); - -/*@null@*/ gchar* -init_fifo(gchar *dir); - -gboolean control_stdin(GIOChannel *gio, GIOCondition condition); -void create_stdin(); - -/*@null@*/ gchar* -init_socket(gchar *dir); - -gboolean control_socket(GIOChannel *chan); -gboolean control_client_socket(GIOChannel *chan); - void update_title(void); -- cgit v1.2.3 From 59af2a8499160a369aceed1bd5cb32109fb5e77c Mon Sep 17 00:00:00 2001 From: koral Date: Thu, 10 Feb 2011 15:20:19 +0100 Subject: Moves additionnal utility functions to util.c. --- src/io.c | 2 ++ src/util.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-- src/util.h | 4 ++++ src/uzbl-core.c | 68 ----------------------------------------------------- 4 files changed, 76 insertions(+), 70 deletions(-) diff --git a/src/io.c b/src/io.c index 80dd666..1c463db 100644 --- a/src/io.c +++ b/src/io.c @@ -1,3 +1,5 @@ +#define _POSIX_SOURCE + #include #include "events.h" diff --git a/src/util.c b/src/util.c index 2da484f..3cf6416 100644 --- a/src/util.c +++ b/src/util.c @@ -6,8 +6,7 @@ #include "util.h" -const XDG_Var XDG[] = -{ +const XDG_Var XDG[] = { { "XDG_CONFIG_HOME", "~/.config" }, { "XDG_DATA_HOME", "~/.local/share" }, { "XDG_CACHE_HOME", "~/.cache" }, @@ -110,6 +109,75 @@ for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void * } +enum exp_type +get_exp_type(const gchar *s) { + /* variables */ + if(*(s+1) == '(') + return EXP_EXPR; + else if(*(s+1) == '{') + return EXP_BRACED_VAR; + else if(*(s+1) == '<') + return EXP_JS; + else if(*(s+1) == '[') + return EXP_ESCAPE; + else + return EXP_SIMPLE_VAR; + + /*@notreached@*/ +return EXP_ERR; +} + + +/* search a PATH style string for an existing file+path combination */ +gchar* +find_existing_file(gchar* path_list) { + int i=0; + int cnt; + gchar **split; + gchar *tmp = NULL; + gchar *executable; + + if(!path_list) + return NULL; + + split = g_strsplit(path_list, ":", 0); + while(split[i]) + i++; + + if(i<=1) { + tmp = g_strdup(split[0]); + g_strfreev(split); + return tmp; + } + else + cnt = i-1; + + i=0; + tmp = g_strdup(split[cnt]); + g_strstrip(tmp); + if(tmp[0] == '/') + executable = g_strdup_printf("%s", tmp+1); + else + executable = g_strdup(tmp); + g_free(tmp); + + while(i Date: Fri, 7 Jan 2011 12:20:52 -0700 Subject: tidying after the history branch merge --- examples/config/config | 3 +-- examples/data/plugins/bind.py | 2 -- examples/data/plugins/history.py | 3 --- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/examples/config/config b/examples/config/config index 2fea0d7..c708576 100644 --- a/examples/config/config +++ b/examples/config/config @@ -200,8 +200,7 @@ set ebind = @mode_bind global,-insert #@ebind du = event APPEND_KEYCMD \@uri #@ebind dt = event APPEND_KEYCMD \@title - -# === Mouse bindings ========================================================= +# --- Mouse bindings --------------------------------------------------------- # Middle click open in new window @bind = sh 'if [ "$1" ]; then echo "event REQ_NEW_WINDOW $1" > "$UZBL_FIFO"; else echo "uri $(xclip -o | sed s/\\\@/%40/g)" > "$UZBL_FIFO"; fi' '\@SELECTED_URI' diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index 261dc5d..41f96c5 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -420,8 +420,6 @@ def match_and_exec(uzbl, bind, depth, keylet, bindlet): if not has_args or on_exec: del uzbl.config['mode'] bindlet.reset() - # cleared by keycmd_exec_current, why is this here? breaks history - #uzbl.clear_current() return True diff --git a/examples/data/plugins/history.py b/examples/data/plugins/history.py index 2ab2ce3..5e9e4e1 100644 --- a/examples/data/plugins/history.py +++ b/examples/data/plugins/history.py @@ -42,7 +42,6 @@ class History(object): self.search_key = None if self._temporary: - print 'popping temporary' return self._temporary.pop() return '' @@ -73,8 +72,6 @@ class History(object): self._temporary.append(cmd) self.cursor = len(self) - 1 - print 'adding temporary', self - def __getitem__(self, i): if i < len(shared_history[self.prompt]): return shared_history[self.prompt][i] -- cgit v1.2.3 From 8ae529244eeefa13b43a08593eedf80cf6d3a2b3 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 10 Jan 2011 10:28:49 -0700 Subject: document history plugin and add example HISTORY_SEARCH binding --- docs/README.uzbl-event-manager | 19 +++++++++++++++++++ examples/config/config | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/docs/README.uzbl-event-manager b/docs/README.uzbl-event-manager index 074811e..92f0228 100644 --- a/docs/README.uzbl-event-manager +++ b/docs/README.uzbl-event-manager @@ -97,3 +97,22 @@ WHITELIST_COOKIE Adds a new whitelist filter. cookies where the component specified by `part` matches the regular expression `re` will be allowed. part can be any of the parts allowed for the BLACKLIST_COOKIE event + +### history.py ### +- Status bar command history +- Connects To: (KEYCMD_EXEC, HISTORY_PREV, HISTORY_NEXT, HISTORY_SEARCH) + +Records commands that are typed into the status bar so that they can be +recalled. The same history is shared by all uzbl instances connected to the +same event manager. + +HISTORY_PREV + Iterates backwards through commands that have been issued (filtered by the + last HISTORY_SEARCH if applicable). + +HISTORY_NEXT + Iterates forwards through commands that have been issued (filtered by the + last HISTORY_SEARCH if applicable). + +HISTORY_SEARCH + Searches backwards through command history for an exact string. diff --git a/examples/config/config b/examples/config/config index c708576..864d37e 100644 --- a/examples/config/config +++ b/examples/config/config @@ -193,7 +193,7 @@ set ebind = @mode_bind global,-insert @ebind = event HISTORY_PREV @ebind = event HISTORY_NEXT -@ebind r_ = event HISTORY_SEARCH %s +@ebind r_ = event HISTORY_SEARCH %s # Keycmd injection/append examples. #@ebind su = event INJECT_KEYCMD \@uri #@ebind st = event INJECT_KEYCMD \@title -- cgit v1.2.3 From d9a413d5a1a80b86c94bb38b278e60ac1d0656c8 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 14 Feb 2011 21:39:16 -0700 Subject: gtk3 needs us to include gtk/gtkx.h --- src/uzbl-core.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uzbl-core.h b/src/uzbl-core.h index f81722d..7a2adca 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -40,6 +40,10 @@ #include #include +#if GTK_CHECK_VERSION(2,91,0) + #include +#endif + #include "cookie-jar.h" #define LENGTH(x) (sizeof x / sizeof x[0]) -- cgit v1.2.3 From cb65c81b4b3d3653122292d6a889dda2b3ec1ef0 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 14 Feb 2011 22:58:42 -0700 Subject: test-expand.c uses functions that are now in util.c --- tests/test-expand.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test-expand.c b/tests/test-expand.c index 06e1619..bc72ecc 100644 --- a/tests/test-expand.c +++ b/tests/test-expand.c @@ -23,6 +23,7 @@ #include #include +#include #include extern UzblCore uzbl; -- cgit v1.2.3 From 90dd4c0ad5e7585b6226a4c591a7783edd6c5f66 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 14 Feb 2011 23:11:04 -0700 Subject: correct per-site-settings example --- examples/data/per-site-settings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/data/per-site-settings b/examples/data/per-site-settings index 78bade4..d02d7a7 100644 --- a/examples/data/per-site-settings +++ b/examples/data/per-site-settings @@ -1,3 +1,3 @@ .* .*/\d+-\w+/(thread|subject|author|date).html - script @data_home/uzbl/scripts/pipermail.js + script @scripts_dir/pipermail.js -- cgit v1.2.3 From f25d19c0fa10451e17d577279d97afe4ba598674 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 14 Feb 2011 23:31:41 -0700 Subject: fix a crash when executing a nonexistent command --- src/uzbl-core.c | 3 ++- tests/test-command.c | 8 ++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 0a90bb9..5d62597 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1533,7 +1533,8 @@ parse_cmd_line(const char *ctl_line, GString *result) { if((work_string[0] != '#')) { /* ignore comments */ GArray *a = g_array_new (TRUE, FALSE, sizeof(gchar*)); const CommandInfo *c = parse_command_parts(work_string, a); - run_parsed_command(c, a, result); + if(c) + run_parsed_command(c, a, result); g_array_free (a, TRUE); } } diff --git a/tests/test-command.c b/tests/test-command.c index d07bf79..6d3d81e 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -297,6 +297,12 @@ test_last_result (void) { g_string_free(result, TRUE); } +void +test_no_such_command (void) { + parse_cmd_line("no-such-command", NULL); + /* if we didn't crash then we're ok! */ +} + int main (int argc, char *argv[]) { /* set up tests */ @@ -315,6 +321,8 @@ main (int argc, char *argv[]) { g_test_add_func("/test-command/last-result", test_last_result); + g_test_add_func("/test-command/no-such-command", test_no_such_command); + /* set up uzbl */ initialize(argc, argv); -- cgit v1.2.3 From e5c2785c5de5230d49be57e172e925a99895b52f Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Tue, 15 Feb 2011 11:33:52 -0700 Subject: remove redundant test --- tests/test-expand.c | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/tests/test-expand.c b/tests/test-expand.c index bc72ecc..bf7e171 100644 --- a/tests/test-expand.c +++ b/tests/test-expand.c @@ -86,19 +86,6 @@ test_COMMIT (void) { g_assert_cmpstr(expand("@COMMIT", 0), ==, uzbl.info.commit); } -void -test_cmd_useragent_simple (void) { - GString* expected = g_string_new("Uzbl (Webkit "); - g_string_append(expected, itos(WEBKIT_MAJOR_VERSION)); - g_string_append(expected, "."); - g_string_append(expected, itos(WEBKIT_MINOR_VERSION)); - g_string_append(expected, "."); - g_string_append(expected, itos(WEBKIT_MICRO_VERSION)); - g_string_append(expected, ")"); - - g_assert_cmpstr(expand("Uzbl (Webkit @{WEBKIT_MAJOR}.@{WEBKIT_MINOR}.@{WEBKIT_MICRO})", 0), ==, g_string_free(expected, FALSE)); -} - void test_cmd_useragent_full (void) { GString* expected = g_string_new("Uzbl (Webkit "); @@ -188,7 +175,6 @@ main (int argc, char *argv[]) { g_test_add_func("/test-expand/@ARCH_UZBL", test_ARCH_UZBL); g_test_add_func("/test-expand/@COMMIT", test_COMMIT); - g_test_add_func("/test-expand/cmd_useragent_simple", test_cmd_useragent_simple); g_test_add_func("/test-expand/cmd_useragent_full", test_cmd_useragent_full); g_test_add_func("/test-expand/escape_markup", test_escape_markup); -- cgit v1.2.3 From 681cb249c31e4e17e3ae9b8f68b10d7f33fea402 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Tue, 15 Feb 2011 11:36:03 -0700 Subject: replace itos() with g_strdup_printf() --- src/callbacks.c | 2 +- src/util.c | 9 --------- src/util.h | 1 - src/uzbl-core.c | 2 +- tests/test-expand.c | 18 ++++++++---------- 5 files changed, 10 insertions(+), 22 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index c261234..9bc5c28 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -441,7 +441,7 @@ void progress_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { (void) param_spec; int progress = webkit_web_view_get_progress(web_view) * 100; - gchar *prg_str = itos(progress); + gchar *prg_str = g_strdup_printf("%d", progress); send_event(LOAD_PROGRESS, prg_str, NULL); g_free(prg_str); } diff --git a/src/util.c b/src/util.c index f56eb57..ead07b5 100644 --- a/src/util.c +++ b/src/util.c @@ -177,15 +177,6 @@ find_existing_file(gchar* path_list) { return NULL; } - -char* -itos(int val) { - char tmp[20]; - - snprintf(tmp, sizeof(tmp), "%i", val); - return g_strdup(tmp); -} - gchar* argv_idx(const GArray *a, const guint idx) { return g_array_index(a, gchar*, idx); diff --git a/src/util.h b/src/util.h index 388c202..87fe53a 100644 --- a/src/util.h +++ b/src/util.h @@ -16,5 +16,4 @@ char* str_replace(const char* search, const char* replace, const char* str gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); enum exp_type get_exp_type(const gchar*); gchar* find_existing_file(gchar*); -char* itos(int val); gchar* argv_idx(const GArray*, const guint); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 129d14a..4c709f7 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1782,7 +1782,7 @@ main (int argc, char* argv[]) { send_event(INSTANCE_START, uzbl.info.pid_str, NULL); if (uzbl.state.plug_mode) { - char *t = itos(gtk_plug_get_id(uzbl.gui.plug)); + char *t = g_strdup_printf("%d", gtk_plug_get_id(uzbl.gui.plug)); send_event(PLUG_CREATED, t, NULL); g_free(t); } diff --git a/tests/test-expand.c b/tests/test-expand.c index bf7e171..d823cfa 100644 --- a/tests/test-expand.c +++ b/tests/test-expand.c @@ -66,14 +66,12 @@ test_useragent (void) { void test_WEBKIT_VERSION (void) { - GString* expected = g_string_new(""); - g_string_append(expected, itos(webkit_major_version())); - g_string_append(expected, " "); - g_string_append(expected, itos(webkit_minor_version())); - g_string_append(expected, " "); - g_string_append(expected, itos(webkit_micro_version())); + gchar *expected = g_strdup_printf("%d %d %d", webkit_major_version(), + webkit_minor_version(), + webkit_micro_version()); - g_assert_cmpstr(expand("@WEBKIT_MAJOR @WEBKIT_MINOR @WEBKIT_MICRO", 0), ==, g_string_free(expected, FALSE)); + g_assert_cmpstr(expand("@WEBKIT_MAJOR @WEBKIT_MINOR @WEBKIT_MICRO", 0), ==, expected); + g_free(expected); } void @@ -89,11 +87,11 @@ test_COMMIT (void) { void test_cmd_useragent_full (void) { GString* expected = g_string_new("Uzbl (Webkit "); - g_string_append(expected, itos(WEBKIT_MAJOR_VERSION)); + g_string_append(expected, g_strdup_printf("%d", WEBKIT_MAJOR_VERSION)); g_string_append(expected, "."); - g_string_append(expected, itos(WEBKIT_MINOR_VERSION)); + g_string_append(expected, g_strdup_printf("%d", WEBKIT_MINOR_VERSION)); g_string_append(expected, "."); - g_string_append(expected, itos(WEBKIT_MICRO_VERSION)); + g_string_append(expected, g_strdup_printf("%d", WEBKIT_MICRO_VERSION)); g_string_append(expected, ") ("); struct utsname unameinfo; -- cgit v1.2.3 From 1a469762d48b69193be9dac1abb8a668f56231f7 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Tue, 15 Feb 2011 12:14:11 -0700 Subject: clean up redundant $PATH-like expansion code --- src/util.c | 141 ++++++++++++++++++++++++++++--------------------------------- src/util.h | 2 +- 2 files changed, 66 insertions(+), 77 deletions(-) diff --git a/src/util.c b/src/util.c index ead07b5..09b0ad7 100644 --- a/src/util.c +++ b/src/util.c @@ -6,6 +6,8 @@ #include "util.h" +gchar* find_existing_file2(gchar *, const gchar *); + const XDG_Var XDG[] = { { "XDG_CONFIG_HOME", "~/.config" }, { "XDG_DATA_HOME", "~/.local/share" }, @@ -16,56 +18,44 @@ const XDG_Var XDG[] = { /*@null@*/ gchar* get_xdg_var (XDG_Var xdg) { - const gchar* actual_value = getenv (xdg.environmental); - const gchar* home = getenv ("HOME"); - gchar* return_value; - - if (! actual_value || strcmp (actual_value, "") == 0) { - if (xdg.default_value) { - return_value = str_replace ("~", home, xdg.default_value); - } else { - return_value = NULL; - } - } else { - return_value = str_replace("~", home, actual_value); + const gchar *actual_value = getenv(xdg.environmental); + const gchar *home = getenv("HOME"); + + if (!actual_value || !actual_value[0]) { + if (!xdg.default_value) + return NULL; + + return str_replace ("~", home, xdg.default_value); } - return return_value; + return str_replace("~", home, actual_value); } /*@null@*/ gchar* -find_xdg_file (int xdg_type, const char* filename) { +find_xdg_file (int xdg_type, const char* basename) { /* xdg_type = 0 => config xdg_type = 1 => data - xdg_type = 2 => cache*/ + xdg_type = 2 => cache */ - gchar* xdgv = get_xdg_var (XDG[xdg_type]); - gchar* temporary_file = g_strconcat (xdgv, filename, NULL); + gchar *xdgv = get_xdg_var(XDG[xdg_type]); + gchar *path = g_strconcat (xdgv, basename, NULL); g_free (xdgv); - gchar* temporary_string; - char* saveptr; - char* buf; - - if (! file_exists (temporary_file) && xdg_type != 2) { - buf = get_xdg_var (XDG[3 + xdg_type]); - temporary_string = (char *) strtok_r (buf, ":", &saveptr); - g_free(buf); + if (file_exists(path)) + return path; - while ((temporary_string = (char * ) strtok_r (NULL, ":", &saveptr)) && ! file_exists (temporary_file)) { - g_free (temporary_file); - temporary_file = g_strconcat (temporary_string, filename, NULL); - } + /* the file doesn't exist in the expected directory. + * check if it exists in one of the system-wide directories. */ + if (!file_exists(path) && xdg_type != 2) { + char *system_dirs = get_xdg_var(XDG[3 + xdg_type]); + path = find_existing_file2(system_dirs, basename); + g_free(system_dirs); } - //g_free (temporary_string); - segfaults. + if(path) + return path; - if (file_exists (temporary_file)) { - return temporary_file; - } else { - g_free(temporary_file); - return NULL; - } + return NULL; } gboolean @@ -127,54 +117,53 @@ get_exp_type(const gchar *s) { return EXP_ERR; } - -/* search a PATH style string for an existing file+path combination */ +/* This function searches the directories in the : separated ($PATH style) + * string 'dirs' for a file named 'basename'. It returns the path of the first + * file found, or NULL if none could be found. + * NOTE: this function modifies the 'dirs' argument. */ gchar* -find_existing_file(gchar* path_list) { - int i=0; - int cnt; - gchar **split; - gchar *tmp = NULL; - gchar *executable; +find_existing_file2(gchar *dirs, const gchar *basename) { + char *saveptr = NULL; + + /* iterate through the : separated elements until we find our file. */ + char *tok = strtok_r(dirs, ":", &saveptr); + char *path = g_strconcat (tok, "/", basename, NULL); + + while (!file_exists(path)) { + g_free(path); + tok = strtok_r(NULL, ":", &saveptr); + if (!tok) + return NULL; /* we've hit the end of the string */ + + path = g_strconcat (tok, "/", basename, NULL); + } + + return path; +} + +/* search a PATH style string for an existing file+path combination. + * everything after the last ':' is assumed to be the name of the file. + * e.g. "/tmp:/home:a/file" will look for /tmp/a/file and /home/a/file. + * + * if there are no :s then the entire thing is taken to be the path. */ +gchar* +find_existing_file(const gchar* path_list) { if(!path_list) return NULL; - split = g_strsplit(path_list, ":", 0); - while(split[i]) - i++; + char *path_list_dup = g_strdup(path_list); - if(i<=1) { - tmp = g_strdup(split[0]); - g_strfreev(split); - return tmp; - } - else - cnt = i-1; + char *basename = strrchr(path_list_dup, ':'); + if(!basename) + return path_list_dup; - i=0; - tmp = g_strdup(split[cnt]); - g_strstrip(tmp); - if(tmp[0] == '/') - executable = g_strdup_printf("%s", tmp+1); - else - executable = g_strdup(tmp); - g_free(tmp); - - while(i Date: Fri, 14 Jan 2011 20:45:56 +0100 Subject: format event strings in send_event send_event now takes a null terminated type, value sequence as arguments vsend_event does the same thing but takes a va_list with arguments. --- src/callbacks.c | 103 ++++++++++++++++++++++++++++--------------------------- src/cookie-jar.c | 16 +++++---- src/events.c | 69 ++++++++++++++++++++++++------------- src/events.h | 6 +++- src/uzbl-core.c | 43 ++++++++++++----------- src/uzbl-core.h | 3 +- 6 files changed, 138 insertions(+), 102 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index 9bc5c28..12bbc14 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -116,7 +116,7 @@ cmd_set_status() { void cmd_load_uri() { - load_uri_imp (uzbl.state.uri); + load_uri_imp (uzbl.state.uri); } void @@ -413,12 +413,12 @@ link_hover_cb (WebKitWebView* page, const gchar* title, const gchar* link, gpoin if(s->last_selected_url && g_strcmp0(s->selected_url, s->last_selected_url)) - send_event(LINK_UNHOVER, s->last_selected_url, NULL); + send_event(LINK_UNHOVER, NULL, TYPE_STR, s->last_selected_url, NULL); - send_event(LINK_HOVER, s->selected_url, NULL); + send_event(LINK_HOVER, NULL, TYPE_STR, s->selected_url, NULL); } else if(s->last_selected_url) { - send_event(LINK_UNHOVER, s->last_selected_url, NULL); + send_event(LINK_UNHOVER, NULL, TYPE_STR, s->last_selected_url, NULL); } update_title(); @@ -433,7 +433,7 @@ title_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { g_free (uzbl.gui.main_title); uzbl.gui.main_title = title ? g_strdup (title) : g_strdup ("(no title)"); update_title(); - send_event(TITLE_CHANGED, uzbl.gui.main_title, NULL); + send_event(TITLE_CHANGED, NULL, TYPE_STR, uzbl.gui.main_title, NULL); g_setenv("UZBL_TITLE", uzbl.gui.main_title, TRUE); } @@ -441,9 +441,7 @@ void progress_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { (void) param_spec; int progress = webkit_web_view_get_progress(web_view) * 100; - gchar *prg_str = g_strdup_printf("%d", progress); - send_event(LOAD_PROGRESS, prg_str, NULL); - g_free(prg_str); + send_event(LOAD_PROGRESS, NULL, TYPE_INT, progress, NULL); } void @@ -454,7 +452,7 @@ load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { WebKitLoadStatus status = webkit_web_view_get_load_status(web_view); switch(status) { case WEBKIT_LOAD_PROVISIONAL: - send_event(LOAD_START, uzbl.state.uri, NULL); + send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri, NULL); break; case WEBKIT_LOAD_COMMITTED: g_free (uzbl.state.uri); @@ -462,10 +460,10 @@ load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { uzbl.state.uri = g_string_free (newuri, FALSE); g_setenv("UZBL_URI", uzbl.state.uri, TRUE); - send_event(LOAD_COMMIT, webkit_web_frame_get_uri (frame), NULL); + send_event(LOAD_COMMIT, NULL, TYPE_STR, webkit_web_frame_get_uri (frame), NULL); break; case WEBKIT_LOAD_FINISHED: - send_event(LOAD_FINISH, webkit_web_frame_get_uri(frame), NULL); + send_event(LOAD_FINISH, NULL, TYPE_STR, webkit_web_frame_get_uri(frame), NULL); break; case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT: break; /* we don't do anything with this (yet) */ @@ -482,7 +480,7 @@ selection_changed_cb(WebKitWebView *webkitwebview, gpointer ud) { webkit_web_view_copy_clipboard(webkitwebview); tmp = gtk_clipboard_wait_for_text(gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)); - send_event(SELECTION_CHANGED, tmp, NULL); + send_event(SELECTION_CHANGED, NULL, TYPE_STR, tmp, NULL); g_free(tmp); } @@ -492,11 +490,12 @@ load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer (void) frame; (void) ud; GError *err = web_err; - gchar *details; - details = g_strdup_printf("%s %d:%s", uri, err->code, err->message); - send_event(LOAD_ERROR, details, NULL); - g_free(details); + send_event (LOAD_ERROR, NULL, + TYPE_STR, uri, + TYPE_INT, err->code, + TYPE_STR, err->message, + NULL); } void @@ -516,7 +515,7 @@ configure_event_cb(GtkWidget* window, GdkEventConfigure* event) { retrieve_geometry(); if(strcmp(lastgeo, uzbl.gui.geometry)) - send_event(GEOMETRY_CHANGED, uzbl.gui.geometry, NULL); + send_event(GEOMETRY_CHANGED, NULL, TYPE_STR, uzbl.gui.geometry, NULL); g_free(lastgeo); return FALSE; @@ -528,10 +527,7 @@ focus_cb(GtkWidget* window, GdkEventFocus* event, void *ud) { (void) event; (void) ud; - if(event->in) - send_event(FOCUS_GAINED, "", NULL); - else - send_event(FOCUS_LOST, "", NULL); + send_event (event->in?FOCUS_GAINED:FOCUS_LOST, NULL, NULL); return FALSE; } @@ -573,9 +569,9 @@ button_press_cb (GtkWidget* window, GdkEventButton* event) { /* left click */ if(event->button == 1) { if((context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)) - send_event(FORM_ACTIVE, "button1", NULL); + send_event(FORM_ACTIVE, NULL, TYPE_STR, "button1", NULL); else if((context & WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT)) - send_event(ROOT_ACTIVE, "button1", NULL); + send_event(ROOT_ACTIVE, NULL, TYPE_STR, "button1", NULL); } else if(event->button == 2 && !(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)) { sendev = TRUE; @@ -588,8 +584,8 @@ button_press_cb (GtkWidget* window, GdkEventButton* event) { if(sendev) { details = g_strdup_printf("Button%d", event->button); - send_event(KEY_PRESS, details, NULL); - g_free(details); + send_event(KEY_PRESS, NULL, TYPE_STR, details, NULL); + g_free (details); } } @@ -617,8 +613,8 @@ button_release_cb (GtkWidget* window, GdkEventButton* event) { if(sendev) { details = g_strdup_printf("Button%d", event->button); - send_event(KEY_RELEASE, details, NULL); - g_free(details); + send_event(KEY_RELEASE, NULL, TYPE_STR, details, NULL); + g_free (details); } } @@ -631,9 +627,11 @@ motion_notify_cb(GtkWidget* window, GdkEventMotion* event, gpointer user_data) { (void) event; (void) user_data; - gchar *details = g_strdup_printf("%.0lf %.0lf %u", event->x, event->y, event->state); - send_event(PTR_MOVE, details, NULL); - g_free(details); + send_event (PTR_MOVE, NULL, + TYPE_FLOAT, event->x, + TYPE_FLOAT, event->y, + TYPE_INT, event->state, + NULL); return FALSE; } @@ -690,7 +688,7 @@ new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, (void) user_data; if (uzbl.state.verbose) - printf("New window requested -> %s \n", webkit_network_request_get_uri (request)); + printf ("New window requested -> %s \n", webkit_network_request_get_uri (request)); /* This event function causes troubles with `target="_blank"` anchors. * Either we: @@ -704,9 +702,9 @@ new_window_cb (WebKitWebView *web_view, WebKitWebFrame *frame, * We are leaving this uncommented as we would rather links open twice * than not at all. */ - send_event(NEW_WINDOW, webkit_network_request_get_uri (request), NULL); + send_event (NEW_WINDOW, NULL, TYPE_STR, webkit_network_request_get_uri (request), NULL); - webkit_web_policy_decision_ignore(policy_decision); + webkit_web_policy_decision_ignore (policy_decision); return TRUE; } @@ -736,7 +734,7 @@ request_starting_cb(WebKitWebView *web_view, WebKitWebFrame *frame, WebKitWebRes (void) response; (void) user_data; - send_event(REQUEST_STARTING, webkit_network_request_get_uri(request), NULL); + send_event (REQUEST_STARTING, NULL, TYPE_STR, webkit_network_request_get_uri(request), NULL); } void @@ -751,7 +749,7 @@ create_web_view_js2_cb (WebKitWebView* web_view, GParamSpec param_spec) { gtk_widget_destroy(GTK_WIDGET(web_view)); } else - send_event(NEW_WINDOW, uri, NULL); + send_event(NEW_WINDOW, NULL, TYPE_STR, uri, NULL); } @@ -792,9 +790,10 @@ download_progress_cb(WebKitDownload *download, GParamSpec *pspec, gpointer user_ const gchar *dest_uri = webkit_download_get_destination_uri(download); const gchar *dest_path = dest_uri + strlen("file://"); - gchar *details = g_strdup_printf("%s %.2lf", dest_path, progress); - send_event(DOWNLOAD_PROGRESS, details, NULL); - g_free(details); + send_event(DOWNLOAD_PROGRESS, NULL, + TYPE_STR, dest_path, + TYPE_FLOAT, progress, + NULL); } void @@ -814,7 +813,7 @@ download_status_cb(WebKitDownload *download, GParamSpec *pspec, gpointer user_da { const gchar *dest_uri = webkit_download_get_destination_uri(download); const gchar *dest_path = dest_uri + strlen("file://"); - send_event(DOWNLOAD_COMPLETE, dest_path, NULL); + send_event(DOWNLOAD_COMPLETE, NULL, TYPE_STR, dest_path, NULL); } } } @@ -905,7 +904,7 @@ download_cb(WebKitWebView *web_view, WebKitDownload *download, gpointer user_dat g_free(rel_path); } - send_event(DOWNLOAD_STARTED, destination_path, NULL); + send_event(DOWNLOAD_STARTED, NULL, TYPE_STR, destination_path, NULL); /* convert absolute path to file:// URI */ gchar *destination_uri = g_strconcat("file://", destination_path, NULL); @@ -926,12 +925,13 @@ scroll_vert_cb(GtkAdjustment *adjust, void *w) gdouble min = gtk_adjustment_get_lower(adjust); gdouble max = gtk_adjustment_get_upper(adjust); gdouble page = gtk_adjustment_get_page_size(adjust); - gchar* details; - details = g_strdup_printf("%g %g %g %g", value, min, max, page); - - send_event(SCROLL_VERT, details, NULL); - g_free(details); + send_event (SCROLL_VERT, NULL, + TYPE_FLOAT, value, + TYPE_FLOAT, min, + TYPE_FLOAT, max, + TYPE_FLOAT, page, + NULL); return (FALSE); } @@ -945,12 +945,13 @@ scroll_horiz_cb(GtkAdjustment *adjust, void *w) gdouble min = gtk_adjustment_get_lower(adjust); gdouble max = gtk_adjustment_get_upper(adjust); gdouble page = gtk_adjustment_get_page_size(adjust); - gchar* details; - details = g_strdup_printf("%g %g %g %g", value, min, max, page); - send_event(SCROLL_HORIZ, details, NULL); - - g_free(details); + send_event (SCROLL_HORIZ, NULL, + TYPE_FLOAT, value, + TYPE_FLOAT, min, + TYPE_FLOAT, max, + TYPE_FLOAT, page, + NULL); return (FALSE); } @@ -1020,3 +1021,5 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { } } } + +/* vi: set et ts=4: */ diff --git a/src/cookie-jar.c b/src/cookie-jar.c index 82a5269..bc7d022 100644 --- a/src/cookie-jar.c +++ b/src/cookie-jar.c @@ -45,13 +45,15 @@ changed(SoupCookieJar *jar, SoupCookie *old_cookie, SoupCookie *new_cookie) { if(cookie->expires) expires = g_strdup_printf ("%d", soup_date_to_time_t (cookie->expires)); - gchar * eventstr = g_strdup_printf ("'%s' '%s' '%s' '%s' '%s' '%s'", - cookie->domain, cookie->path, cookie->name, cookie->value, scheme, expires?expires:""); - if(new_cookie) - send_event(ADD_COOKIE, eventstr, NULL); - else - send_event(DELETE_COOKIE, eventstr, NULL); - g_free(eventstr); + send_event (new_cookie ? ADD_COOKIE : DELETE_COOKIE, NULL, + TYPE_STR, cookie->domain, + TYPE_STR, cookie->path, + TYPE_STR, cookie->name, + TYPE_STR, cookie->value, + TYPE_STR, scheme, + TYPE_STR, expires ? expires : "", + NULL); + if(expires) g_free(expires); } diff --git a/src/events.c b/src/events.c index 31a95d5..b9b5a18 100644 --- a/src/events.c +++ b/src/events.c @@ -137,32 +137,53 @@ send_event_stdout(GString *msg) { fflush(stdout); } +void +vsend_event(int type, const gchar *custom_event, va_list vargs) { + GString *event_message = g_string_sized_new (512); + if (type >= LAST_EVENT) + return; + const gchar *event = custom_event ? custom_event : event_table[type]; + + int next; + g_string_printf (event_message, "EVENT [%s] %s", + uzbl.state.instance_name, event); + + while ((next = va_arg (vargs, int)) != 0) { + switch(next) { + case TYPE_INT: + g_string_append_printf (event_message, " %d", va_arg (vargs, int)); + break; + case TYPE_STR: + g_string_append_printf (event_message, " %s", va_arg (vargs, char*)); + break; + case TYPE_FLOAT: + // ‘float’ is promoted to ‘double’ when passed through ‘...’ + g_string_append_printf (event_message, " %.2g", va_arg (vargs, double)); + break; + } + } + + g_string_append_c(event_message, '\n'); + + if (uzbl.state.events_stdout) + send_event_stdout (event_message); + send_event_socket (event_message); + + g_string_free (event_message, TRUE); +} + /* * build event string and send over the supported interfaces * custom_event == NULL indicates an internal event */ void -send_event(int type, const gchar *details, const gchar *custom_event) { - GString *event_message = g_string_new(""); - - /* check for custom events */ - if(custom_event) { - g_string_printf(event_message, "EVENT [%s] %s %s\n", - uzbl.state.instance_name, custom_event, details); - } - /* check wether we support the internal event */ - else if(type < LAST_EVENT) { - g_string_printf(event_message, "EVENT [%s] %s %s\n", - uzbl.state.instance_name, event_table[type], details); - } - - if(event_message->str) { - if(uzbl.state.events_stdout) - send_event_stdout(event_message); - send_event_socket(event_message); - - g_string_free(event_message, TRUE); - } +send_event(int type, const gchar *custom_event, ...) { + va_list vargs, vacopy; + va_start (vargs, custom_event); + va_copy (vacopy, vargs); + vsend_event (type, custom_event, vacopy); + va_end (vacopy); + va_end (vargs); } /* Transform gdk key events to our own events */ @@ -181,12 +202,14 @@ key_to_event(guint keyval, gint mode) { ucs[ulen] = 0; send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - ucs, NULL); + NULL, TYPE_STR, ucs, NULL); } /* send keysym for non-printable chars */ else { send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - gdk_keyval_name(keyval), NULL); + NULL, TYPE_STR, gdk_keyval_name(keyval), NULL); } } + +/* vi: set et ts=4: */ diff --git a/src/events.h b/src/events.h index 4edc5ab..8e75097 100644 --- a/src/events.h +++ b/src/events.h @@ -7,6 +7,7 @@ #define __EVENTS__ #include +#include /* Event system */ enum event_type { @@ -38,7 +39,10 @@ void send_event_stdout(GString *msg); void -send_event(int type, const gchar *details, const gchar *custom_event); +vsend_event(int type, const gchar *custom_event, va_list vargs); + +void +send_event(int type, const gchar *custom_event, ...) G_GNUC_NULL_TERMINATED; void key_to_event(guint keyval, gint mode); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 4c709f7..7c0e2c3 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -337,7 +337,7 @@ expand(const char* s, guint recurse) { void clean_up(void) { if (uzbl.info.pid_str) { - send_event(INSTANCE_EXIT, uzbl.info.pid_str, NULL); + send_event (INSTANCE_EXIT, NULL, TYPE_STR, uzbl.info.pid_str, NULL); g_free(uzbl.info.pid_str); uzbl.info.pid_str = NULL; } @@ -560,7 +560,7 @@ builtins() { g_string_append_c(command_list, ' '); } - send_event(BUILTINS, command_list->str, NULL); + send_event(BUILTINS, NULL, TYPE_STR, command_list->str, NULL); g_string_free(command_list, TRUE); } @@ -597,7 +597,7 @@ event(WebKitWebView *page, GArray *argv, GString *result) { else return; - send_event(0, split[1]?split[1]:"", event_name->str); + send_event(0, event_name->str, TYPE_STR, split[1] ? split[1] : "", NULL); g_string_free(event_name, TRUE); g_strfreev(split); @@ -640,11 +640,11 @@ include(WebKitWebView *page, GArray *argv, GString *result) { if((path = find_existing_file(path))) { if(!for_each_line_in_file(path, parse_cmd_line_cb, NULL)) { gchar *tmp = g_strdup_printf("File %s can not be read.", path); - send_event(COMMAND_ERROR, tmp, NULL); + send_event(COMMAND_ERROR, NULL, TYPE_STR, tmp, NULL); g_free(tmp); } - send_event(FILE_INCLUDED, path, NULL); + send_event(FILE_INCLUDED, NULL, TYPE_STR, path, NULL); g_free(path); } } @@ -1103,13 +1103,17 @@ run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { if(strcmp("set", c->key) && strcmp("event", c->key) && strcmp("request", c->key)) { - GString *tmp = g_string_new(c->key); + // FIXME, build string inside send_event + GString *param = g_string_new(""); const gchar *p; guint i = 0; while ((p = argv_idx(a, i++))) - g_string_append_printf(tmp, " '%s'", p); - send_event(COMMAND_EXECUTED, tmp->str, NULL); - g_string_free(tmp, TRUE); + g_string_append_printf(param, " '%s'", p); + send_event(COMMAND_EXECUTED, NULL, + TYPE_STR, c->key, + TYPE_STR, param->str, + NULL); + g_string_free(param, TRUE); } if(result) { @@ -1177,9 +1181,10 @@ parse_command(const char *cmd, const char *params, GString *result) { g_array_free (a, TRUE); } else { - gchar *tmp = g_strconcat(cmd, " ", params, NULL); - send_event(COMMAND_ERROR, tmp, NULL); - g_free(tmp); + send_event(COMMAND_ERROR, NULL, + TYPE_STR, cmd, + TYPE_STR, params ? params : "", + NULL); } } @@ -1238,7 +1243,7 @@ set_var_value(const gchar *name, gchar *val) { g_string_append_printf(msg, " float %f", *c->ptr.f); } - send_event(VARIABLE_SET, msg->str, NULL); + send_event(VARIABLE_SET, NULL, TYPE_STR, msg->str, NULL); g_string_free(msg,TRUE); /* invoke a command specific function */ @@ -1265,7 +1270,7 @@ set_var_value(const gchar *name, gchar *val) { msg = g_string_new(name); g_string_append_printf(msg, " str %s", buf); - send_event(VARIABLE_SET, msg->str, NULL); + send_event(VARIABLE_SET, NULL, TYPE_STR, msg->str, NULL); g_string_free(msg,TRUE); } update_title(); @@ -1463,7 +1468,7 @@ settings_init () { if (s->config_file) { if (!for_each_line_in_file(s->config_file, parse_cmd_line_cb, NULL)) { gchar *tmp = g_strdup_printf("File %s can not be read.", s->config_file); - send_event(COMMAND_ERROR, tmp, NULL); + send_event(COMMAND_ERROR, NULL, TYPE_STR, tmp, NULL); g_free(tmp); } g_setenv("UZBL_CONFIG", s->config_file, TRUE); @@ -1571,7 +1576,7 @@ dump_var_hash_as_event(gpointer k, gpointer v, gpointer ud) { g_string_append_printf(msg, " float %f", *c->ptr.f); } - send_event(VARIABLE_SET, msg->str, NULL); + send_event(VARIABLE_SET, NULL, TYPE_STR, msg->str, NULL); g_string_free(msg, TRUE); } @@ -1779,12 +1784,10 @@ main (int argc, char* argv[]) { uzbl.info.pid_str = g_strdup_printf("%d", getpid()); g_setenv("UZBL_PID", uzbl.info.pid_str, TRUE); - send_event(INSTANCE_START, uzbl.info.pid_str, NULL); + send_event(INSTANCE_START, NULL, TYPE_STR, uzbl.info.pid_str, NULL); if (uzbl.state.plug_mode) { - char *t = g_strdup_printf("%d", gtk_plug_get_id(uzbl.gui.plug)); - send_event(PLUG_CREATED, t, NULL); - g_free(t); + send_event(PLUG_CREATED, NULL, TYPE_INT, gtk_plug_get_id (uzbl.gui.plug), NULL); } /* Generate an event with a list of built in commands */ diff --git a/src/uzbl-core.h b/src/uzbl-core.h index a10c0ce..649f159 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -241,7 +241,8 @@ extern UzblCore uzbl; /* Main Uzbl object */ typedef void sigfunc(int); /* Uzbl variables */ -enum ptr_type {TYPE_INT, TYPE_STR, TYPE_FLOAT}; +/* uzbl variables */ +enum ptr_type {TYPE_INT = 1, TYPE_STR, TYPE_FLOAT}; typedef struct { enum ptr_type type; union { -- cgit v1.2.3 From 2b7539061d8d437ef1507a8cf68d9b565d07c66e Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 15 Jan 2011 22:14:42 +0100 Subject: new function append_escaped appends a string after escaping it --- src/util.c | 31 ++++++++++++++++++++++++++++++- src/util.h | 4 ++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/util.c b/src/util.c index ead07b5..345bf2f 100644 --- a/src/util.c +++ b/src/util.c @@ -108,7 +108,6 @@ for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void * return FALSE; } - enum exp_type get_exp_type(const gchar *s) { /* variables */ @@ -181,3 +180,33 @@ gchar* argv_idx(const GArray *a, const guint idx) { return g_array_index(a, gchar*, idx); } + +GString * +append_escaped (GString *dest, const gchar *src) { + g_assert(dest); + g_assert(src); + + // Hint that we are going to append another string. + int oldlen = dest->len; + g_string_set_size (dest, dest->len + strlen(src) * 2); + g_string_truncate (dest, oldlen); + + // Append src char by char with baddies escaped + for (const gchar *p = src; *p; p++) { + switch (*p) { + case '\\': + g_string_append (dest, "\\\\"); + break; + case '\'': + g_string_append (dest, "\\'"); + break; + case '\n': + g_string_append (dest, "\\n"); + break; + default: + g_string_append_c (dest, *p); + break; + } + } + return dest; +} diff --git a/src/util.h b/src/util.h index 87fe53a..db19930 100644 --- a/src/util.h +++ b/src/util.h @@ -17,3 +17,7 @@ gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gcha enum exp_type get_exp_type(const gchar*); gchar* find_existing_file(gchar*); gchar* argv_idx(const GArray*, const guint); +/** + * appends `src' to `dest' with backslash, single-quotes and newlines in + * `src' escaped */ +GString * append_escaped (GString *dest, const gchar *src); -- cgit v1.2.3 From 3d658d9c10809ec4ec76fb557535a2f6383cff45 Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 15 Jan 2011 22:15:29 +0100 Subject: quote and escape strings in events --- src/callbacks.c | 8 ++--- src/events.c | 19 ++++++++--- src/uzbl-core.c | 99 ++++++++++++++++++++++++++++++++++++--------------------- src/uzbl-core.h | 5 +-- 4 files changed, 83 insertions(+), 48 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index 12bbc14..78a5090 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -569,9 +569,9 @@ button_press_cb (GtkWidget* window, GdkEventButton* event) { /* left click */ if(event->button == 1) { if((context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)) - send_event(FORM_ACTIVE, NULL, TYPE_STR, "button1", NULL); + send_event(FORM_ACTIVE, NULL, TYPE_NAME, "button1", NULL); else if((context & WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT)) - send_event(ROOT_ACTIVE, NULL, TYPE_STR, "button1", NULL); + send_event(ROOT_ACTIVE, NULL, TYPE_NAME, "button1", NULL); } else if(event->button == 2 && !(context & WEBKIT_HIT_TEST_RESULT_CONTEXT_EDITABLE)) { sendev = TRUE; @@ -584,7 +584,7 @@ button_press_cb (GtkWidget* window, GdkEventButton* event) { if(sendev) { details = g_strdup_printf("Button%d", event->button); - send_event(KEY_PRESS, NULL, TYPE_STR, details, NULL); + send_event(KEY_PRESS, NULL, TYPE_NAME, details, NULL); g_free (details); } } @@ -613,7 +613,7 @@ button_release_cb (GtkWidget* window, GdkEventButton* event) { if(sendev) { details = g_strdup_printf("Button%d", event->button); - send_event(KEY_RELEASE, NULL, TYPE_STR, details, NULL); + send_event(KEY_RELEASE, NULL, TYPE_NAME, details, NULL); g_free (details); } } diff --git a/src/events.c b/src/events.c index b9b5a18..e8c42a3 100644 --- a/src/events.c +++ b/src/events.c @@ -5,6 +5,7 @@ #include "uzbl-core.h" #include "events.h" +#include "util.h" UzblCore uzbl; @@ -140,6 +141,7 @@ send_event_stdout(GString *msg) { void vsend_event(int type, const gchar *custom_event, va_list vargs) { GString *event_message = g_string_sized_new (512); + if (type >= LAST_EVENT) return; const gchar *event = custom_event ? custom_event : event_table[type]; @@ -149,16 +151,23 @@ vsend_event(int type, const gchar *custom_event, va_list vargs) { uzbl.state.instance_name, event); while ((next = va_arg (vargs, int)) != 0) { + g_string_append_c(event_message, ' '); switch(next) { case TYPE_INT: - g_string_append_printf (event_message, " %d", va_arg (vargs, int)); + g_string_append_printf (event_message, "%d", va_arg (vargs, int)); break; case TYPE_STR: - g_string_append_printf (event_message, " %s", va_arg (vargs, char*)); + g_string_append_c (event_message, '\''); + append_escaped (event_message, va_arg (vargs, char*)); + g_string_append_c (event_message, '\''); + break; + case TYPE_FORMATTEDSTR: + case TYPE_NAME: + g_string_append (event_message, va_arg (vargs, char*)); break; case TYPE_FLOAT: // ‘float’ is promoted to ‘double’ when passed through ‘...’ - g_string_append_printf (event_message, " %.2g", va_arg (vargs, double)); + g_string_append_printf (event_message, "%.2f", va_arg (vargs, double)); break; } } @@ -202,12 +211,12 @@ key_to_event(guint keyval, gint mode) { ucs[ulen] = 0; send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - NULL, TYPE_STR, ucs, NULL); + NULL, TYPE_FORMATTEDSTR, ucs, NULL); } /* send keysym for non-printable chars */ else { send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - NULL, TYPE_STR, gdk_keyval_name(keyval), NULL); + NULL, TYPE_NAME, gdk_keyval_name(keyval), NULL); } } diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 7c0e2c3..ca936c1 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -337,7 +337,7 @@ expand(const char* s, guint recurse) { void clean_up(void) { if (uzbl.info.pid_str) { - send_event (INSTANCE_EXIT, NULL, TYPE_STR, uzbl.info.pid_str, NULL); + send_event (INSTANCE_EXIT, NULL, TYPE_INT, getpid(), NULL); g_free(uzbl.info.pid_str); uzbl.info.pid_str = NULL; } @@ -597,7 +597,7 @@ event(WebKitWebView *page, GArray *argv, GString *result) { else return; - send_event(0, event_name->str, TYPE_STR, split[1] ? split[1] : "", NULL); + send_event(0, event_name->str, TYPE_FORMATTEDSTR, split[1] ? split[1] : "", NULL); g_string_free(event_name, TRUE); g_strfreev(split); @@ -1110,8 +1110,8 @@ run_parsed_command(const CommandInfo *c, GArray *a, GString *result) { while ((p = argv_idx(a, i++))) g_string_append_printf(param, " '%s'", p); send_event(COMMAND_EXECUTED, NULL, - TYPE_STR, c->key, - TYPE_STR, param->str, + TYPE_NAME, c->key, + TYPE_FORMATTEDSTR, param->str, NULL); g_string_free(param, TRUE); } @@ -1153,7 +1153,9 @@ parse_command_parts(const gchar *line, GArray *a) { c = g_hash_table_lookup(uzbl.behave.commands, tokens[0]); if(!c) { - send_event(COMMAND_ERROR, exp_line, NULL); + send_event(COMMAND_ERROR, NULL, + TYPE_STR, exp_line, + NULL); g_free(exp_line); g_strfreev(tokens); return NULL; @@ -1182,7 +1184,7 @@ parse_command(const char *cmd, const char *params, GString *result) { g_array_free (a, TRUE); } else { send_event(COMMAND_ERROR, NULL, - TYPE_STR, cmd, + TYPE_NAME, cmd, TYPE_STR, params ? params : "", NULL); } @@ -1220,32 +1222,41 @@ set_var_value(const gchar *name, gchar *val) { char *endp = NULL; char *buf = NULL; char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; - GString *msg; if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { if(!c->writeable) return FALSE; - msg = g_string_new(name); - - /* check for the variable type */ - if (c->type == TYPE_STR) { + switch(c->type) { + case TYPE_STR: buf = g_strdup(val); g_free(*c->ptr.s); *c->ptr.s = buf; - g_string_append_printf(msg, " str %s", buf); - - } else if(c->type == TYPE_INT) { + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "str", + TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", + NULL); + break; + case TYPE_INT: *c->ptr.i = (int)strtoul(val, &endp, 10); - g_string_append_printf(msg, " int %d", *c->ptr.i); - - } else if (c->type == TYPE_FLOAT) { + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "int", + TYPE_INT, *c->ptr.i, + NULL); + break; + case TYPE_FLOAT: *c->ptr.f = strtod(val, &endp); - g_string_append_printf(msg, " float %f", *c->ptr.f); + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "float", + TYPE_FLOAT, *c->ptr.f, + NULL); + break; + default: + g_assert_not_reached(); } - send_event(VARIABLE_SET, NULL, TYPE_STR, msg->str, NULL); - g_string_free(msg,TRUE); - /* invoke a command specific function */ if(c->func) c->func(); } else { @@ -1268,10 +1279,11 @@ set_var_value(const gchar *name, gchar *val) { g_hash_table_insert(uzbl.comm.proto_var, g_strdup(name), (gpointer) c); - msg = g_string_new(name); - g_string_append_printf(msg, " str %s", buf); - send_event(VARIABLE_SET, NULL, TYPE_STR, msg->str, NULL); - g_string_free(msg,TRUE); + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "str", + TYPE_STR, buf, + NULL); } update_title(); return TRUE; @@ -1561,23 +1573,36 @@ void dump_var_hash_as_event(gpointer k, gpointer v, gpointer ud) { (void) ud; uzbl_cmdprop *c = v; - GString *msg; if(!c->dump) return; /* check for the variable type */ - msg = g_string_new((char *)k); - if (c->type == TYPE_STR) { - g_string_append_printf(msg, " str %s", *c->ptr.s ? *c->ptr.s : " "); - } else if(c->type == TYPE_INT) { - g_string_append_printf(msg, " int %d", *c->ptr.i); - } else if (c->type == TYPE_FLOAT) { - g_string_append_printf(msg, " float %f", *c->ptr.f); + switch(c->type) { + case TYPE_STR: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, (char*)k, + TYPE_NAME, "str", + TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", + NULL); + break; + case TYPE_INT: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, (char*)k, + TYPE_NAME, "int", + TYPE_INT, *c->ptr.i, + NULL); + break; + case TYPE_FLOAT: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, (char*)k, + TYPE_NAME, "float", + TYPE_FLOAT, *c->ptr.f, + NULL); + break; + default: + g_assert_not_reached(); } - - send_event(VARIABLE_SET, NULL, TYPE_STR, msg->str, NULL); - g_string_free(msg, TRUE); } void @@ -1784,7 +1809,7 @@ main (int argc, char* argv[]) { uzbl.info.pid_str = g_strdup_printf("%d", getpid()); g_setenv("UZBL_PID", uzbl.info.pid_str, TRUE); - send_event(INSTANCE_START, NULL, TYPE_STR, uzbl.info.pid_str, NULL); + send_event(INSTANCE_START, NULL, TYPE_INT, getpid(), NULL); if (uzbl.state.plug_mode) { send_event(PLUG_CREATED, NULL, TYPE_INT, gtk_plug_get_id (uzbl.gui.plug), NULL); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 649f159..9e72511 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -241,8 +241,9 @@ extern UzblCore uzbl; /* Main Uzbl object */ typedef void sigfunc(int); /* Uzbl variables */ -/* uzbl variables */ -enum ptr_type {TYPE_INT = 1, TYPE_STR, TYPE_FLOAT}; +enum ptr_type {TYPE_INT = 1, TYPE_STR, TYPE_FLOAT, + TYPE_NAME, TYPE_FORMATTEDSTR // used by send_event +}; typedef struct { enum ptr_type type; union { -- cgit v1.2.3 From 713c9bb02b9bab9956f8e5439a0d47e7dedfaf24 Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 15 Jan 2011 22:16:42 +0100 Subject: grok quoted strings in a select places in the em --- examples/data/plugins/config.py | 10 +++++++++- examples/data/plugins/cookies.py | 11 +++++++++-- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/data/plugins/config.py b/examples/data/plugins/config.py index ed2d761..dde4ae1 100644 --- a/examples/data/plugins/config.py +++ b/examples/data/plugins/config.py @@ -2,8 +2,16 @@ from re import compile from types import BooleanType from UserDict import DictMixin +_unquote = compile("'(.*?)'|\"(.*?)\"") +def unquote(s): + m = _unquote.match(s) + if m is not None: + return unicode(m.group(1)).decode('string_escape') + return unicode(s).decode('string_escape') + + valid_key = compile('^[A-Za-z0-9_\.]+$').match -types = {'int': int, 'float': float, 'str': unicode} +types = {'int': int, 'float': float, 'str': unquote} escape = lambda s: unicode(s).replace('\n', '\\n') class Config(DictMixin): diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index 6ee8798..05a8901 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -7,9 +7,16 @@ import os, re # these are symbolic names for the components of the cookie tuple symbolic = {'domain': 0, 'path':1, 'name':2, 'value':3, 'scheme':4, 'expires':5} -_splitquoted = re.compile("( |\\\".*?\\\"|'.*?')") +_unquote = re.compile("'(.*?)'|\"(.*?)\"") +def unquote(s): + m = _unquote.match(s) + if m is not None: + return unicode(m.group(1)).decode('string_escape') + return unicode(s).decode('string_escape') + +_splitquoted = re.compile("( |\"(?:\\\\.|[^\"])*?\"|'(?:\\\\.|[^'])*?')") def splitquoted(text): - return [str(p.strip('\'"')) for p in _splitquoted.split(text) if p.strip()] + return [unquote(p) for p in _splitquoted.split(text) if p.strip()] # allows for partial cookies # ? allow wildcard in key -- cgit v1.2.3 From bed2433630f6d0d78e8b829c46b00c3ab301b512 Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 16 Jan 2011 21:34:20 +0100 Subject: use empty string instead of null for event args * url * clipboard text --- src/callbacks.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index 78a5090..a40057c 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -452,7 +452,7 @@ load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { WebKitLoadStatus status = webkit_web_view_get_load_status(web_view); switch(status) { case WEBKIT_LOAD_PROVISIONAL: - send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri, NULL); + send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri ? uzbl.state.uri : "", NULL); break; case WEBKIT_LOAD_COMMITTED: g_free (uzbl.state.uri); @@ -480,7 +480,7 @@ selection_changed_cb(WebKitWebView *webkitwebview, gpointer ud) { webkit_web_view_copy_clipboard(webkitwebview); tmp = gtk_clipboard_wait_for_text(gtk_clipboard_get (GDK_SELECTION_CLIPBOARD)); - send_event(SELECTION_CHANGED, NULL, TYPE_STR, tmp, NULL); + send_event(SELECTION_CHANGED, NULL, TYPE_STR, tmp ? tmp : "", NULL); g_free(tmp); } -- cgit v1.2.3 From 3594f35e565ebf210b583bcc3c4df042e0dc4191 Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 21:57:16 +0100 Subject: move common function related to escaping to Plugin --- examples/data/plugins/bind.py | 9 --------- examples/data/plugins/config.py | 14 +++----------- examples/data/plugins/cookies.py | 11 ----------- examples/data/scripts/uzbl-event-manager | 20 +++++++++++++++++++- 4 files changed, 22 insertions(+), 32 deletions(-) diff --git a/examples/data/plugins/bind.py b/examples/data/plugins/bind.py index 41f96c5..69fd863 100644 --- a/examples/data/plugins/bind.py +++ b/examples/data/plugins/bind.py @@ -164,15 +164,6 @@ def split_glob(glob): return (mods, glob) -def unquote(str): - '''Remove quotation marks around string.''' - - if str and str[0] == str[-1] and str[0] in ['"', "'"]: - str = str[1:-1] - - return str - - class Bind(object): # Class attribute to hold the number of Bind classes created. diff --git a/examples/data/plugins/config.py b/examples/data/plugins/config.py index dde4ae1..b7ecf42 100644 --- a/examples/data/plugins/config.py +++ b/examples/data/plugins/config.py @@ -2,17 +2,7 @@ from re import compile from types import BooleanType from UserDict import DictMixin -_unquote = compile("'(.*?)'|\"(.*?)\"") -def unquote(s): - m = _unquote.match(s) - if m is not None: - return unicode(m.group(1)).decode('string_escape') - return unicode(s).decode('string_escape') - - valid_key = compile('^[A-Za-z0-9_\.]+$').match -types = {'int': int, 'float': float, 'str': unquote} -escape = lambda s: unicode(s).replace('\n', '\\n') class Config(DictMixin): def __init__(self, uzbl): @@ -57,7 +47,7 @@ class Config(DictMixin): value = int(value) else: - value = escape(value) + value = value.encode('unicode_escape') if not force and key in self and self[key] == value: return @@ -90,6 +80,8 @@ def parse_set_event(uzbl, args): # plugin init hook def init(uzbl): + global types + types = {'int': int, 'float': float, 'str': unquote} export(uzbl, 'config', Config(uzbl)) connect(uzbl, 'VARIABLE_SET', parse_set_event) diff --git a/examples/data/plugins/cookies.py b/examples/data/plugins/cookies.py index 05a8901..e29ee36 100644 --- a/examples/data/plugins/cookies.py +++ b/examples/data/plugins/cookies.py @@ -7,17 +7,6 @@ import os, re # these are symbolic names for the components of the cookie tuple symbolic = {'domain': 0, 'path':1, 'name':2, 'value':3, 'scheme':4, 'expires':5} -_unquote = re.compile("'(.*?)'|\"(.*?)\"") -def unquote(s): - m = _unquote.match(s) - if m is not None: - return unicode(m.group(1)).decode('string_escape') - return unicode(s).decode('string_escape') - -_splitquoted = re.compile("( |\"(?:\\\\.|[^\"])*?\"|'(?:\\\\.|[^'])*?')") -def splitquoted(text): - return [unquote(p) for p in _splitquoted.split(text) if p.strip()] - # allows for partial cookies # ? allow wildcard in key def match(key, cookie): diff --git a/examples/data/scripts/uzbl-event-manager b/examples/data/scripts/uzbl-event-manager index 8ad3af7..d47318a 100755 --- a/examples/data/scripts/uzbl-event-manager +++ b/examples/data/scripts/uzbl-event-manager @@ -34,6 +34,7 @@ import socket import sys import time import weakref +import re from collections import defaultdict from functools import partial from glob import glob @@ -169,13 +170,16 @@ class EventHandler(object): self.callback(uzbl, *args, **kwargs) + + + class Plugin(object): '''Plugin module wrapper object.''' # Special functions exported from the Plugin instance to the # plugin namespace. special_functions = ['require', 'export', 'export_dict', 'connect', - 'connect_dict', 'logger'] + 'connect_dict', 'logger', 'unquote', 'splitquoted'] def __init__(self, parent, name, path, plugin): @@ -291,6 +295,20 @@ class Plugin(object): assert plugin in self.parent.plugins, self.logger.critical( 'plugin %r required by plugin %r' (plugin, self.name)) + @classmethod + def unquote(cls, s): + '''Removes quotation marks around strings if any and interprets + \\-escape sequences using `unicode_escape`''' + if s and s[0] == s[-1] and s[0] in ['"', "'"]: + s = s[1:-1] + return unicode(s).decode('unicode_escape') + + _splitquoted = re.compile("( |\"(?:\\\\.|[^\"])*?\"|'(?:\\\\.|[^'])*?')") + @classmethod + def splitquoted(cls, text): + '''Splits string on whitespace while respecting quotations''' + return [cls.unquote(p) for p in cls._splitquoted.split(text) if p.strip()] + class Uzbl(object): def __init__(self, parent, child_socket): -- cgit v1.2.3 From e2e1f6203fa8e9bdbae567cfbec1ee341c10282b Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 24 Jan 2011 18:59:17 +0100 Subject: don't escape in Config.set escapes should be done by caller checks for plain newline as these would break stuff --- examples/data/plugins/config.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/data/plugins/config.py b/examples/data/plugins/config.py index b7ecf42..c9bdf67 100644 --- a/examples/data/plugins/config.py +++ b/examples/data/plugins/config.py @@ -47,7 +47,8 @@ class Config(DictMixin): value = int(value) else: - value = value.encode('unicode_escape') + value = unicode(value) + assert '\n' not in value if not force and key in self and self[key] == value: return -- cgit v1.2.3 From d3bde90f9ec4ef80f7130de0cc9b802c9537a700 Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 24 Jan 2011 19:49:04 +0100 Subject: assert that NAME arguments are valid names --- src/events.c | 7 ++++++- src/uzbl-core.c | 9 +++++++-- src/uzbl-core.h | 1 + 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/events.c b/src/events.c index e8c42a3..174ff75 100644 --- a/src/events.c +++ b/src/events.c @@ -145,6 +145,7 @@ vsend_event(int type, const gchar *custom_event, va_list vargs) { if (type >= LAST_EVENT) return; const gchar *event = custom_event ? custom_event : event_table[type]; + char* str; int next; g_string_printf (event_message, "EVENT [%s] %s", @@ -162,9 +163,13 @@ vsend_event(int type, const gchar *custom_event, va_list vargs) { g_string_append_c (event_message, '\''); break; case TYPE_FORMATTEDSTR: - case TYPE_NAME: g_string_append (event_message, va_arg (vargs, char*)); break; + case TYPE_NAME: + str = va_arg (vargs, char*); + g_assert (valid_name (str)); + g_string_append (event_message, str); + break; case TYPE_FLOAT: // ‘float’ is promoted to ‘double’ when passed through ‘...’ g_string_append_printf (event_message, "%.2f", va_arg (vargs, double)); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index ca936c1..6809441 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1216,12 +1216,17 @@ move_statusbar() { return; } +gboolean +valid_name(const gchar* name) { + char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; + return strpbrk(name, invalid_chars) == NULL; +} + gboolean set_var_value(const gchar *name, gchar *val) { uzbl_cmdprop *c = NULL; char *endp = NULL; char *buf = NULL; - char *invalid_chars = "\t^°!\"§$%&/()=?'`'+~*'#-:,;@<>| \\{}[]¹²³¼½"; if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { if(!c->writeable) return FALSE; @@ -1261,7 +1266,7 @@ set_var_value(const gchar *name, gchar *val) { if(c->func) c->func(); } else { /* check wether name violates our naming scheme */ - if(strpbrk(name, invalid_chars)) { + if(!valid_name(name)) { if (uzbl.state.verbose) printf("Invalid variable name: %s\n", name); return FALSE; diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 9e72511..3240fc6 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -317,6 +317,7 @@ void handle_authentication (SoupSession *session, void handle_cookies (SoupSession *session, SoupMessage *msg, gpointer user_data); +gboolean valid_name(const gchar* name); void set_var(WebKitWebView *page, GArray *argv, GString *result); void act_dump_config(); void act_dump_config_as_events(); -- cgit v1.2.3 From 70b9ba7440c5164c90f61ddf4d988f32019a5ecc Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 7 Feb 2011 11:11:41 +0100 Subject: use string_escape to remove \-escapes unicode_escape fails on non-ascii chars. --- examples/data/scripts/uzbl-event-manager | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/examples/data/scripts/uzbl-event-manager b/examples/data/scripts/uzbl-event-manager index d47318a..cb462c7 100755 --- a/examples/data/scripts/uzbl-event-manager +++ b/examples/data/scripts/uzbl-event-manager @@ -298,10 +298,10 @@ class Plugin(object): @classmethod def unquote(cls, s): '''Removes quotation marks around strings if any and interprets - \\-escape sequences using `unicode_escape`''' + \\-escape sequences using `string_escape`''' if s and s[0] == s[-1] and s[0] in ['"', "'"]: s = s[1:-1] - return unicode(s).decode('unicode_escape') + return s.encode('utf-8').decode('string_escape').decode('utf-8') _splitquoted = re.compile("( |\"(?:\\\\.|[^\"])*?\"|'(?:\\\\.|[^'])*?')") @classmethod @@ -987,3 +987,5 @@ if __name__ == "__main__": daemon_actions[action]() logger.debug('process CPU time: %f' % time.clock()) + +# vi: set et ts=4: -- cgit v1.2.3 From 3cb9af3b4457f5c6aec1eae2acf552aad8a3e6db Mon Sep 17 00:00:00 2001 From: keis Date: Sun, 23 Jan 2011 22:06:33 +0100 Subject: support quoted events in a few more places * downloads * on_event handlers --- examples/data/plugins/downloads.py | 18 +++++++++++++----- examples/data/plugins/on_event.py | 6 ++++++ 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/examples/data/plugins/downloads.py b/examples/data/plugins/downloads.py index 7bf32d7..8d796ce 100644 --- a/examples/data/plugins/downloads.py +++ b/examples/data/plugins/downloads.py @@ -31,7 +31,11 @@ def update_download_section(uzbl): if uzbl.config.get('downloads', '') != result: uzbl.config['downloads'] = result -def download_started(uzbl, destination_path): +def download_started(uzbl, args): + # parse the arguments + args = splitquoted(args) + destination_path = args[0] + # add to the list of active downloads global ACTIVE_DOWNLOADS ACTIVE_DOWNLOADS[destination_path] = (0.0,) @@ -41,9 +45,9 @@ def download_started(uzbl, destination_path): def download_progress(uzbl, args): # parse the arguments - s = args.rindex(' ') - destination_path = args[:s] - progress = float(args[s+1:]) + args = splitquoted(args) + destination_path = args[0] + progress = float(args[1]) # update the progress global ACTIVE_DOWNLOADS @@ -52,7 +56,11 @@ def download_progress(uzbl, args): # update the status bar variable update_download_section(uzbl) -def download_complete(uzbl, destination_path): +def download_complete(uzbl, args): + # parse the arguments + args = splitquoted(args) + destination_path = args[0] + # remove from the list of active downloads global ACTIVE_DOWNLOADS del ACTIVE_DOWNLOADS[destination_path] diff --git a/examples/data/plugins/on_event.py b/examples/data/plugins/on_event.py index 5142275..32f09e2 100644 --- a/examples/data/plugins/on_event.py +++ b/examples/data/plugins/on_event.py @@ -24,6 +24,10 @@ def event_handler(uzbl, *args, **kargs): '''This function handles all the events being watched by various on_event definitions and responds accordingly.''' + # Could be connected to a EM internal event that can use anything as args + if len(args) == 1 and isinstance(args[0], basestring): + args = splitquoted(args[0]) + events = uzbl.on_events event = kargs['on_event'] if event not in events: @@ -80,3 +84,5 @@ def cleanup(uzbl): del handlers[:] uzbl.on_events.clear() + +# vi: set et ts=4: -- cgit v1.2.3 From 22502eaa7a8966f0170efc22927465d2c25e10fa Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Tue, 15 Feb 2011 14:50:04 -0700 Subject: further tidying of utility functions --- src/util.c | 58 ++++++++++++++++++--------------------------------------- src/util.h | 4 ---- src/uzbl-core.c | 14 ++++++++++++++ 3 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src/util.c b/src/util.c index 09b0ad7..cc51048 100644 --- a/src/util.c +++ b/src/util.c @@ -21,12 +21,11 @@ get_xdg_var (XDG_Var xdg) { const gchar *actual_value = getenv(xdg.environmental); const gchar *home = getenv("HOME"); - if (!actual_value || !actual_value[0]) { - if (!xdg.default_value) - return NULL; + if (!actual_value || !actual_value[0]) + actual_value = xdg.default_value; - return str_replace ("~", home, xdg.default_value); - } + if (!actual_value) + return NULL; return str_replace("~", home, actual_value); } @@ -44,18 +43,16 @@ find_xdg_file (int xdg_type, const char* basename) { if (file_exists(path)) return path; + if (xdg_type == 2) + return NULL; + /* the file doesn't exist in the expected directory. * check if it exists in one of the system-wide directories. */ - if (!file_exists(path) && xdg_type != 2) { - char *system_dirs = get_xdg_var(XDG[3 + xdg_type]); - path = find_existing_file2(system_dirs, basename); - g_free(system_dirs); - } + char *system_dirs = get_xdg_var(XDG[3 + xdg_type]); + path = find_existing_file2(system_dirs, basename); + g_free(system_dirs); - if(path) - return path; - - return NULL; + return path; } gboolean @@ -85,36 +82,17 @@ for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void * GIOChannel *chan = g_io_channel_new_file(path, "r", NULL); - if (chan) { - while (g_io_channel_read_line(chan, &line, &len, NULL, NULL) == G_IO_STATUS_NORMAL) { - callback(line, user_data); - g_free(line); - } - g_io_channel_unref (chan); + if (!chan) + return FALSE; - return TRUE; + while (g_io_channel_read_line(chan, &line, &len, NULL, NULL) == G_IO_STATUS_NORMAL) { + callback(line, user_data); + g_free(line); } - return FALSE; -} - + g_io_channel_unref (chan); -enum exp_type -get_exp_type(const gchar *s) { - /* variables */ - if(*(s+1) == '(') - return EXP_EXPR; - else if(*(s+1) == '{') - return EXP_BRACED_VAR; - else if(*(s+1) == '<') - return EXP_JS; - else if(*(s+1) == '[') - return EXP_ESCAPE; - else - return EXP_SIMPLE_VAR; - - /*@notreached@*/ -return EXP_ERR; + return TRUE; } /* This function searches the directories in the : separated ($PATH style) diff --git a/src/util.h b/src/util.h index d2e7f6c..126166b 100644 --- a/src/util.h +++ b/src/util.h @@ -6,14 +6,10 @@ typedef struct { gchar* default_value; } XDG_Var; -enum exp_type {EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS, EXP_ESCAPE}; - - gchar* get_xdg_var(XDG_Var xdg); gchar* find_xdg_file(int xdg_type, const char* filename); gboolean file_exists(const char* filename); char* str_replace(const char* search, const char* replace, const char* string); gboolean for_each_line_in_file(const gchar *path, void (*callback)(const gchar *l, void *c), void *user_data); -enum exp_type get_exp_type(const gchar*); gchar* find_existing_file(const gchar*); gchar* argv_idx(const GArray*, const guint); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 4c709f7..a4d43af 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -165,6 +165,20 @@ create_var_to_name_hash() { /* --- UTILITY FUNCTIONS --- */ +enum exp_type { + EXP_ERR, EXP_SIMPLE_VAR, EXP_BRACED_VAR, EXP_EXPR, EXP_JS, EXP_ESCAPE +}; + +enum exp_type +get_exp_type(const gchar *s) { + switch(*(s+1)) { + case '(': return EXP_EXPR; + case '{': return EXP_BRACED_VAR; + case '<': return EXP_JS; + case '[': return EXP_ESCAPE; + default: return EXP_SIMPLE_VAR; + } +} /* * recurse == 1: don't expand '@(command)@' -- cgit v1.2.3 From 05357cb88daca76428437a960f973f8a4058938f Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Wed, 16 Feb 2011 17:19:58 -0700 Subject: add taylanub's formfiller as-is --- examples/data/scripts/formfiller.js | 67 ++++++++ examples/data/scripts/formfiller.sh | 329 +++++++++++++++--------------------- 2 files changed, 205 insertions(+), 191 deletions(-) create mode 100644 examples/data/scripts/formfiller.js mode change 100755 => 100644 examples/data/scripts/formfiller.sh diff --git a/examples/data/scripts/formfiller.js b/examples/data/scripts/formfiller.js new file mode 100644 index 0000000..abf0162 --- /dev/null +++ b/examples/data/scripts/formfiller.js @@ -0,0 +1,67 @@ +uzbl.formfiller = { + + dump: function() { + var rv = ''; + var allFrames = new Array(window); + for ( f=0; f -# files contain lines like: !profile= -# (fieldtype): -# profile_name should be replaced with a name that will tell sth about that -# profile -# fieldtype can be checkbox, text or password, textarea - only for information -# pupropse (auto-generated) - don't change that -# -# Texteares: for textareas edited text can be now splitted into more lines. -# If there will be text, that doesn't match key line: -# (fieldtype): -# then it will be considered as a multiline for the first field above it -# Keep in mind, that if you make more than one line for fileds like input -# text fields, then all lines will be inserted into as one line -# -# Checkboxes/radio-buttons: to uncheck it type on of the following after the -# colon: -# no -# off -# 0 -# unchecked -# false -# or leave it blank, even without spaces -# otherwise it will be considered as checked -# -# user arg 1: -# edit: force editing the file (falls back to new if not found) -# new: start with a new file. -# load: try to load from file into form -# add: try to add another profile to an existing file -# once: edit form using external editor -# -# something else (or empty): if file not available: new, otherwise load. +# action +# new: add new profile template (creates file if not found), then edit +# edit: edit file (fall back to 'new' if file not found) +# load: load from file +# once: use temporary file to edit form once +# (empty): if file not available, new; otherwise, load # -DMENU_ARGS="-i" -DMENU_SCHEMA="formfiller" -DMENU_LINES="3" -DMENU_PROMPT="Choose profile" -DMENU_OPTIONS="vertical resize" +action=$1 +shift $# + +keydir=$HOME/etc/uzbl/dforms + +mkdir -p "$keydir" || exit + +Ed () { "${VTERM:-xterm}" -e "${VISUAL:-${EDITOR:-vi}}" "$@"; } + +Dmenu () +{ + dmenu -p "choose profile" \ + ${DMENU_FONT+-fn "$DMENU_FONT"} \ + -nb "#0f0f0f" -nf "#4e7093" -sb "#003d7c" -sf "#3a9bff" \ + -l 4 \ + "$@" +} + +domain=${UZBL_URI#*://} +domain=${domain%%/*} + +test "$domain" || exit + +file=$keydir/$domain + +GenForm () +{ + echo 'js uzbl.formfiller.dump();' \ + | socat - unix-connect:"$UZBL_SOCKET" \ + | awk ' + /^formfillerstart$/ { + while (getline) { + if ( /^%!end/ ) exit + print + } + } + ' +} + +GetOption () + if [ $(grep -c '^!profile' "$1") -gt 1 ] + then sed -n 's/^!profile=//p' "$1" | Dmenu + else sed -n 's/^!profile=//p' "$1" + fi + +ParseProfile () +{ + sed "/^>/d; /^!profile=$1$/,/^!/!d; /^!/d" +} + +ParseFields () +{ + awk '/^%/ { + + sub ( /%/, "" ) + + split( $0, parts, /\(|\)|\{|\}/ ) + + field = $0 + sub ( /[^:]*:/, "", field ) + + if ( parts[2] ~ /(text|password|search)/ ) + printf( "js uzbl.formfiller.insert(\"%s\",\"%s\",\"%s\",0);\n", + parts[1], parts[2], field ) + + else if ( parts[2] ~ /(checkbox|radio)/ ) + printf( "js uzbl.formfiller.insert(\"%s\",\"%s\",\"%s\",%s);\n", + parts[1], parts[2], parts[3], field ) + + else if ( parts[2] == "textarea" ) { + field = "" + while (getline) { + if ( /^%/ ) break + sub ( /^\\/, "" ) + gsub ( /"/, "\\\"" ) + gsub ( /\\/, "\\\\" ) + field = field $0 "\\n" + } + printf( "js uzbl.formfiller.insert(\"%s\",\"%s\",\"%s\",0);\n", + parts[1], parts[2], field ) + } + + }' +} + +New () +{ + { echo '!profile=NAME_THIS_PROFILE' + GenForm | sed 's/^!/\\!/' + echo '!' + } >> "$file" + chmod 600 "$file" + Ed "$file" +} + +Edit () + if [ -e "$file" ] + then Ed "$file" + else New + fi -. $UZBL_UTIL_DIR/dmenu.sh -. $UZBL_UTIL_DIR/editor.sh -. $UZBL_UTIL_DIR/uzbl-dir.sh +Load () +{ + test -e "$file" || exit -RAND=$(dd if=/dev/urandom count=1 2> /dev/null | cksum | cut -c 1-5) -MODELINE="> vim:ft=formfiller" + option=$(GetOption "$file") -[ -d "$(dirname $UZBL_FORMS_DIR)" ] || exit 1 -[ -d $UZBL_FORMS_DIR ] || mkdir $UZBL_FORMS_DIR || exit 1 + case $option in *[!a-zA-Z0-9_-]*) exit 1; esac -action=$1 + ParseProfile $option < "$file" \ + | ParseFields \ + | sed 's/@/\\@/' \ + > "$UZBL_FIFO" +} -domain=$(echo $UZBL_URI | sed 's/\(http\|https\):\/\/\([^\/]\+\)\/.*/\2/') - -if [ "$action" != 'edit' -a "$action" != 'new' -a "$action" != 'load' -a "$action" != 'add' -a "$action" != 'once' ]; then - action="new" - [ -e "$UZBL_FORMS_DIR/$domain" ] && action="load" -elif [ "$action" = 'edit' ] && [ ! -e "$UZBL_FORMS_DIR/$domain" ]; then - action="new" -fi - -dumpFunction="function dump() { \ - var rv=''; \ - var allFrames = new Array(window); \ - for(f=0;f/d' -i $tmpfile - - sed 's/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):\(off\|no\|false\|unchecked\|0\|$\)/\1{\2}(\3):0/I;s/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[^0]\+/\1{\2}(\3):1/I' -i $UZBL_FORMS_DIR/$domain - fields=$(cat $UZBL_FORMS_DIR/$domain | \ - sed -n "/^!profile=${option}/,/^!profile=/p" | \ - sed '/^!profile=/d' | \ - sed 's/^\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):/%{>\1\2):<}%/' | \ - sed 's/^\(.\+\)$/<{br}>\1/' | \ - tr -d '\n' | \ - sed 's/<{br}>%{>\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):<}%/\\n\1\2):/g') - printf '%s\n' "${fields}" | \ - sed -n -e "s/\([^(]\+\)(\(password\|text\|search\|textarea\)\+):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\2', '\3', 0);/p" | \ - sed -e 's/@/\\@/g;s/<{br}>/\\\\n/g' | socat - unix-connect:$UZBL_SOCKET - printf '%s\n' "${fields}" | \ - sed -n -e "s/\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\3', '\2', \4);/p" | \ - sed -e 's/@/\\@/g' | socat - unix-connect:$UZBL_SOCKET -elif [ "$action" = "once" ]; then - tmpfile=$(mktemp) - printf 'js %s dump(); \n' "$dumpFunction" | \ - socat - unix-connect:$UZBL_SOCKET | \ - sed -n '/^[^(]\+([^)]\+):/p' > $tmpfile - echo "$MODELINE" >> $tmpfile - $UZBL_EDITOR $tmpfile - - [ -e $tmpfile ] || exit 2 - - # Remove comments - sed '/^>/d' -i $tmpfile - - sed 's/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):\(off\|no\|false\|unchecked\|0\|$\)/\1{\2}(\3):0/I;s/^\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[^0]\+/\1{\2}(\3):1/I' -i $tmpfile - fields=$(cat $tmpfile | \ - sed 's/^\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):/%{>\1\2):<}%/' | \ - sed 's/^\(.\+\)$/<{br}>\1/' | \ - tr -d '\n' | \ - sed 's/<{br}>%{>\([^(]\+(\)\(radio\|checkbox\|text\|search\|textarea\|password\)):<}%/\\n\1\2):/g') - printf '%s\n' "${fields}" | \ - sed -n -e "s/\([^(]\+\)(\(password\|text\|search\|textarea\)\+):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\2', '\3', 0);/p" | \ - sed -e 's/@/\\@/g;s/<{br}>/\\\\n/g' | socat - unix-connect:$UZBL_SOCKET - printf '%s\n' "${fields}" | \ - sed -n -e "s/\([^{]\+\){\([^}]*\)}(\(radio\|checkbox\)):[ ]*\(.\+\)/js $insertFunction; insert('\1', '\3', '\2', \4);/p" | \ - sed -e 's/@/\\@/g' | socat - unix-connect:$UZBL_SOCKET - rm -f $tmpfile -else - if [ "$action" = 'new' -o "$action" = 'add' ]; then - [ "$action" = 'new' ] && echo "$MODELINE" > $UZBL_FORMS_DIR/$domain - echo "!profile=NAME_THIS_PROFILE$RAND" >> $UZBL_FORMS_DIR/$domain - # - # 2. and 3. line (tr -d and sed) are because, on gmail login for example, - # tag is splited into lines - # ex: - # - # So, tr removes all new lines, and sed inserts new line after each > - # Next sed selects only tags and only with type = "text" or = "password" - # If type is first and name is second, then another sed will change their order - # so the last sed will make output - # text_from_the_name_attr(text or password): - # - # login(text): - # passwd(password): - # - printf 'js %s dump(); \n' "$dumpFunction" | \ - socat - unix-connect:$UZBL_SOCKET | \ - sed -n '/^[^(]\+([^)]\+):/p' >> $UZBL_FORMS_DIR/$domain - fi - [ -e "$UZBL_FORMS_DIR/$domain" ] || exit 3 #this should never happen, but you never know. - $UZBL_EDITOR "$UZBL_FORMS_DIR/$domain" #TODO: if user aborts save in editor, the file is already overwritten -fi + GenForm > "$tmpfile" + chmod 600 "$tmpfile" + + Ed "$tmpfile" + + test -e "$tmpfile" && + ParseFields < "$tmpfile" \ + | sed 's/@/\\@' \ + > "$UZBL_FIFO" +} -# vim:fileencoding=utf-8:sw=4 +case $action in + new) New; Load ;; + edit) Edit; Load ;; + load) Load ;; + once) Once ;; + '') if [ -e "$file" ]; then Load; else New; Load; fi ;; + *) exit 1 +esac -- cgit v1.2.3 From 82fa30898161800e2a4fdc8129d1f99cdd4c545e Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Wed, 16 Feb 2011 21:34:10 -0700 Subject: formfiller: use the util dir for file location, editor and dmenu config --- examples/data/scripts/formfiller.sh | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) mode change 100644 => 100755 examples/data/scripts/formfiller.sh diff --git a/examples/data/scripts/formfiller.sh b/examples/data/scripts/formfiller.sh old mode 100644 new mode 100755 index 9b35fbe..3dc9dc4 --- a/examples/data/scripts/formfiller.sh +++ b/examples/data/scripts/formfiller.sh @@ -9,29 +9,18 @@ # action=$1 -shift $# -keydir=$HOME/etc/uzbl/dforms +. "$UZBL_UTIL_DIR/uzbl-dir.sh" +. "$UZBL_UTIL_DIR/editor.sh" -mkdir -p "$keydir" || exit - -Ed () { "${VTERM:-xterm}" -e "${VISUAL:-${EDITOR:-vi}}" "$@"; } - -Dmenu () -{ - dmenu -p "choose profile" \ - ${DMENU_FONT+-fn "$DMENU_FONT"} \ - -nb "#0f0f0f" -nf "#4e7093" -sb "#003d7c" -sf "#3a9bff" \ - -l 4 \ - "$@" -} +mkdir -p "$UZBL_FORMS_DIR" || exit domain=${UZBL_URI#*://} domain=${domain%%/*} test "$domain" || exit -file=$keydir/$domain +file=$UZBL_FORMS_DIR/$domain GenForm () { @@ -48,10 +37,18 @@ GenForm () } GetOption () +{ + DMENU_SCHEME=formfiller + DMENU_PROMPT="choose profile" + DMENU_LINES=4 + + . "$UZBL_UTIL_DIR/dmenu.sh" + if [ $(grep -c '^!profile' "$1") -gt 1 ] - then sed -n 's/^!profile=//p' "$1" | Dmenu + then sed -n 's/^!profile=//p' "$1" | $DMENU else sed -n 's/^!profile=//p' "$1" fi +} ParseProfile () { @@ -100,12 +97,12 @@ New () echo '!' } >> "$file" chmod 600 "$file" - Ed "$file" + $UZBL_EDITOR "$file" } Edit () if [ -e "$file" ] - then Ed "$file" + then $UZBL_EDITOR "$file" else New fi @@ -131,7 +128,7 @@ Once () GenForm > "$tmpfile" chmod 600 "$tmpfile" - Ed "$tmpfile" + $UZBL_EDITOR "$tmpfile" test -e "$tmpfile" && ParseFields < "$tmpfile" \ -- cgit v1.2.3 From 303aeea88f99ec3505a17f36e5ee420830fe298a Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Wed, 16 Feb 2011 21:52:10 -0700 Subject: updated config for the new formfiller --- examples/config/config | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/config/config b/examples/config/config index bc07b0c..1ec462d 100644 --- a/examples/config/config +++ b/examples/config/config @@ -69,6 +69,10 @@ set download_handler = sync_spawn @scripts_dir/download.sh # Load commit handlers @on_event LOAD_COMMIT @set_status recv + # add some javascript to the page for other 'js' and 'script' commands to access later. +@on_event LOAD_COMMIT js uzbl = {}; +@on_event LOAD_COMMIT script @scripts_dir/formfiller.js + # Userscripts/per-site-settings. See the script and the example configuration for details #@on_event LOAD_COMMIT spawn @scripts_dir/per-site-settings.py @data_home/uzbl/per-site-settings -- cgit v1.2.3 From 8b8c458c2ddd249f833fed0b94c6d3d5596a9056 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Wed, 16 Feb 2011 21:53:24 -0700 Subject: added documentation for formfiller data format --- docs/formfiller-data-format | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 docs/formfiller-data-format diff --git a/docs/formfiller-data-format b/docs/formfiller-data-format new file mode 100644 index 0000000..f42114c --- /dev/null +++ b/docs/formfiller-data-format @@ -0,0 +1,35 @@ +FORMFILLER FILE FORMAT + +lines starting with '>' are ignored + +a file consists of profile definitions +lines between profile definitions are ignored + +a line starting with '!profile=' introduces a profile definition +the rest of that line is taken as the profile name +profile names must match the RE /^[a-zA-Z0-9_-]*$/ +a line starting with '!' terminates the profile definition +the rest of that line is ignored + +a profile definition consists of field definitions +lines between field definitions are ignored + +a line starting with '%' introduces a field definition +(details depend on the field type) +the rest of that line shall be in the format ... + 'name(type){value}:checked' for checkbox/radio + 'name(type):value' for text/password/search + 'name(type):' for textarea +where name/type/value/checked are the input field's HTML attribute values, + 'name' always being percent encoded, 'checked' being a JS boolean, + and 'value' being percent encoded if type is checkbox/radio +for all types but textarea, the field definition ends with that single line +for textarea, all lines up to (but excluding) one starting with '%' make up the 'value' +the rest of that line starting with '%' is ignored + +for all lines, a leading '\', if present, is removed + +-- + +a once-edit temporary file consists only of field definitions, + and lines starting with '!' or '>' are not special -- cgit v1.2.3 From fecdd721bd94a5705ca5ccb74739d3fb902c01ba Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 17 Feb 2011 09:14:14 -0700 Subject: added taylanub to AUTHORS --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index f5144a1..373fc3f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -75,6 +75,7 @@ In alphabetical order: Simon Lipp (sloonz) - various patches, EM contributions Sylvester Johansson (scj) - form filler script & different take on link follower Tassilo Horn (tsdh) - $VISUAL patch + Taylan Ulrich Bayırlı (taylanub) - updated form filler Thorsten Wilms - logo design Tom Adams (holizz) - few patches, cookies.py, gtkplug/socket & proof of concept uzbl_tabbed.py, scheme_handler Uli Schlachter (psychon) - basic mime_policy_cb & Makefile patch -- cgit v1.2.3 From b7a47b3f58e6fa05d56577ea6425d353a41ddb86 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 17 Feb 2011 09:27:08 -0700 Subject: fix 'print' on stdin --- src/io.c | 7 ++++++- src/uzbl-core.c | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/io.c b/src/io.c index 1e85237..b84780e 100644 --- a/src/io.c +++ b/src/io.c @@ -123,9 +123,14 @@ control_stdin(GIOChannel *gio, GIOCondition condition) { if ( (ret == G_IO_STATUS_ERROR) || (ret == G_IO_STATUS_EOF) ) return FALSE; - parse_cmd_line(ctl_line, NULL); + GString *result = g_string_new(""); + + parse_cmd_line(ctl_line, result); g_free(ctl_line); + puts(result->str); + g_string_free(result, TRUE); + return TRUE; } diff --git a/src/uzbl-core.c b/src/uzbl-core.c index a4d43af..936dbdc 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -622,6 +622,9 @@ print(WebKitWebView *page, GArray *argv, GString *result) { (void) page; (void) result; gchar* buf; + if(!result) + return; + buf = expand(argv_idx(argv, 0), 0); g_string_assign(result, buf); g_free(buf); -- cgit v1.2.3 From 1d2e5fad17d7e396dc6b7f5748bffd2a23e80e25 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 17 Feb 2011 12:56:56 -0700 Subject: update tests for new event escaping --- tests/test-command.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test-command.c b/tests/test-command.c index 6d3d81e..55bf316 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -152,7 +152,7 @@ test_set_variable (struct EventFixture *ef, const void *data) { /* set a string */ parse_cmd_line("set useragent = Uzbl browser kthxbye!", NULL); - ASSERT_EVENT(ef, "VARIABLE_SET useragent str Uzbl browser kthxbye!"); + ASSERT_EVENT(ef, "VARIABLE_SET useragent str 'Uzbl browser kthxbye!'"); g_assert_cmpstr("Uzbl browser kthxbye!", ==, uzbl.net.useragent); /* set an int */ @@ -168,7 +168,7 @@ test_set_variable (struct EventFixture *ef, const void *data) { parse_cmd_line(g_string_free(cmd, FALSE), NULL); ev = g_string_new("EVENT [" INSTANCE_NAME "] VARIABLE_SET zoom_level float "); - g_string_append_printf(ev, "%f\n", 0.25); + g_string_append_printf(ev, "%.2f\n", 0.25); read_event(ef); g_assert_cmpstr(g_string_free(ev, FALSE), ==, ef->event_buffer); @@ -188,13 +188,13 @@ test_set_variable (struct EventFixture *ef, const void *data) { /* set a custom variable */ parse_cmd_line("set nonexistant_variable = Some Value", NULL); - ASSERT_EVENT(ef, "VARIABLE_SET nonexistant_variable str Some Value"); + ASSERT_EVENT(ef, "VARIABLE_SET nonexistant_variable str 'Some Value'"); uzbl_cmdprop *c = g_hash_table_lookup(uzbl.comm.proto_var, "nonexistant_variable"); g_assert_cmpstr("Some Value", ==, *c->ptr.s); /* set a custom variable with expansion */ parse_cmd_line("set an_expanded_variable = Test @(echo expansion)@", NULL); - ASSERT_EVENT(ef, "VARIABLE_SET an_expanded_variable str Test expansion"); + ASSERT_EVENT(ef, "VARIABLE_SET an_expanded_variable str 'Test expansion'"); c = g_hash_table_lookup(uzbl.comm.proto_var, "an_expanded_variable"); g_assert_cmpstr("Test expansion", ==, *c->ptr.s); } -- cgit v1.2.3 From e3b04d3ae9fb6dfeff5e6099784586b54591814e Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 17 Feb 2011 13:08:04 -0700 Subject: minor refactor of VARIABLE_SET event code --- src/uzbl-core.c | 78 +++++++++++++++++++++++++-------------------------------- 1 file changed, 34 insertions(+), 44 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 6809441..26b3dba 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1222,6 +1222,36 @@ valid_name(const gchar* name) { return strpbrk(name, invalid_chars) == NULL; } +void +send_set_var_event(const char *name, const uzbl_cmdprop *c) { + /* check for the variable type */ + switch(c->type) { + case TYPE_STR: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "str", + TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", + NULL); + break; + case TYPE_INT: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "int", + TYPE_INT, *c->ptr.i, + NULL); + break; + case TYPE_FLOAT: + send_event (VARIABLE_SET, NULL, + TYPE_NAME, name, + TYPE_NAME, "float", + TYPE_FLOAT, *c->ptr.f, + NULL); + break; + default: + g_assert_not_reached(); + } +} + gboolean set_var_value(const gchar *name, gchar *val) { uzbl_cmdprop *c = NULL; @@ -1236,32 +1266,19 @@ set_var_value(const gchar *name, gchar *val) { buf = g_strdup(val); g_free(*c->ptr.s); *c->ptr.s = buf; - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "str", - TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", - NULL); break; case TYPE_INT: *c->ptr.i = (int)strtoul(val, &endp, 10); - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "int", - TYPE_INT, *c->ptr.i, - NULL); break; case TYPE_FLOAT: *c->ptr.f = strtod(val, &endp); - send_event (VARIABLE_SET, NULL, - TYPE_NAME, name, - TYPE_NAME, "float", - TYPE_FLOAT, *c->ptr.f, - NULL); break; default: g_assert_not_reached(); } + send_set_var_event(name, c); + /* invoke a command specific function */ if(c->func) c->func(); } else { @@ -1579,35 +1596,8 @@ dump_var_hash_as_event(gpointer k, gpointer v, gpointer ud) { (void) ud; uzbl_cmdprop *c = v; - if(!c->dump) - return; - - /* check for the variable type */ - switch(c->type) { - case TYPE_STR: - send_event (VARIABLE_SET, NULL, - TYPE_NAME, (char*)k, - TYPE_NAME, "str", - TYPE_STR, *c->ptr.s ? *c->ptr.s : " ", - NULL); - break; - case TYPE_INT: - send_event (VARIABLE_SET, NULL, - TYPE_NAME, (char*)k, - TYPE_NAME, "int", - TYPE_INT, *c->ptr.i, - NULL); - break; - case TYPE_FLOAT: - send_event (VARIABLE_SET, NULL, - TYPE_NAME, (char*)k, - TYPE_NAME, "float", - TYPE_FLOAT, *c->ptr.f, - NULL); - break; - default: - g_assert_not_reached(); - } + if(c->dump) + send_set_var_event(k, c); } void -- cgit v1.2.3 From 7b04611f2813c619c38a6a3424ab73497804373d Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 17 Feb 2011 13:11:24 -0700 Subject: update AUTHORS --- AUTHORS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index f5144a1..5e7ef07 100644 --- a/AUTHORS +++ b/AUTHORS @@ -35,7 +35,7 @@ In alphabetical order: Daiki Ueno (ueno) - fix for crash when opening image in new window Damien Leon - misc Daniel M. Hackney - documentation cleanups - David Keijser (keis) - the add_cookie/delete_cookie + distributor system, various C and python patches. + David Keijser (keis) - the add_cookie/delete_cookie + distributor system, consistent event syntax, various C and python patches. Devon Jones - uzbl_tabbed: bring_to_front Dieter Plaetinck (Dieter@be) - several contributions Dmytro Milinevskyy - uzbl-tabbed useability patches -- cgit v1.2.3 From bf3ffb03fd15377022f0cbffcbb041ec1812fb49 Mon Sep 17 00:00:00 2001 From: Jake Probst Date: Thu, 17 Feb 2011 14:41:52 -0800 Subject: menu_image_add is now not totally useless and gives the image url as an argument --- src/callbacks.c | 33 +++++++++++++++++++++++++++------ src/uzbl-core.c | 3 ++- src/uzbl-core.h | 1 + 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index fa2ed1f..b603ea0 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -934,16 +934,29 @@ scroll_horiz_cb(GtkAdjustment *adjust, void *w) } void -run_menu_command(GtkWidget *menu, const char *line) { +run_menu_command(GtkWidget *menu, MenuItem *mi) { (void) menu; - parse_cmd_line(line, NULL); + if (mi->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { + gchar* uri; + g_object_get(mi->hittest, "image-uri", &uri, NULL); + + gchar* cmd = g_malloc(strlen(uri) + strlen(mi->cmd) + 5); + g_sprintf(cmd, "%s %s", mi->cmd, uri); + + parse_cmd_line(cmd, NULL); + + g_free(cmd); + g_free(uri); + } + else { + parse_cmd_line(mi->cmd, NULL); + } } void populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { - (void) v; (void) c; GUI *g = &uzbl.gui; GtkWidget *item; @@ -958,11 +971,19 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { if((context = get_click_context(NULL)) == -1) return; - for(i=0; i < uzbl.gui.menu_items->len; i++) { hit = 0; mi = g_ptr_array_index(uzbl.gui.menu_items, i); + if (mi->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { + GdkEventButton ev; + gint x, y; + gdk_window_get_pointer(gtk_widget_get_window(v), &x, &y, NULL); + ev.x = x; + ev.y = y; + mi->hittest = webkit_web_view_get_hit_test_result(v, &ev); + } + if((mi->context > WEBKIT_HIT_TEST_RESULT_CONTEXT_DOCUMENT) && (context & mi->context)) { if(mi->issep) { @@ -973,7 +994,7 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { else { item = gtk_menu_item_new_with_label(mi->name); g_signal_connect(item, "activate", - G_CALLBACK(run_menu_command), mi->cmd); + G_CALLBACK(run_menu_command), mi); gtk_menu_shell_append(GTK_MENU_SHELL(m), item); gtk_widget_show(item); } @@ -991,7 +1012,7 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { else { item = gtk_menu_item_new_with_label(mi->name); g_signal_connect(item, "activate", - G_CALLBACK(run_menu_command), mi->cmd); + G_CALLBACK(run_menu_command), mi); gtk_menu_shell_append(GTK_MENU_SHELL(m), item); gtk_widget_show(item); } diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 877dbda..5953a11 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1398,7 +1398,8 @@ move_statusbar() { } g_object_unref(uzbl.gui.scrolled_win); g_object_unref(uzbl.gui.mainbar); - gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); + if (!uzbl.state.plug_mode) + gtk_widget_grab_focus (GTK_WIDGET (uzbl.gui.web_view)); return; } diff --git a/src/uzbl-core.h b/src/uzbl-core.h index f81722d..429b892 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -488,6 +488,7 @@ typedef struct { gchar *cmd; gboolean issep; guint context; + WebKitHitTestResult* hittest; } MenuItem; -- cgit v1.2.3 From a299262011692b86b39ed5911418ca5b83f4a68e Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 19 Feb 2011 18:38:06 +0100 Subject: fix crash when using uri without argument --- src/uzbl-core.c | 5 ++++- tests/test-command.c | 8 +++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index b2e7a7a..779f378 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -737,7 +737,8 @@ act_dump_config_as_events() { void load_uri(WebKitWebView *web_view, GArray *argv, GString *result) { (void) web_view; (void) result; - set_var_value("uri", argv_idx(argv, 0)); + gchar * uri = argv_idx(argv, 0); + set_var_value("uri", uri ? uri : ""); } /* Javascript*/ @@ -1275,6 +1276,8 @@ set_var_value(const gchar *name, gchar *val) { char *endp = NULL; char *buf = NULL; + g_assert(val != NULL); + if( (c = g_hash_table_lookup(uzbl.comm.proto_var, name)) ) { if(!c->writeable) return FALSE; diff --git a/tests/test-command.c b/tests/test-command.c index 55bf316..6b55fb3 100644 --- a/tests/test-command.c +++ b/tests/test-command.c @@ -282,6 +282,11 @@ test_js (void) { g_string_free(result, TRUE); } +void test_uri(void) { + /* Testing for a crash, not crashing is a pass */ + parse_cmd_line("uri", NULL); +} + void test_last_result (void) { GString *result = g_string_new(""); @@ -313,6 +318,7 @@ main (int argc, char *argv[]) { g_test_add("/test-command/event", struct EventFixture, NULL, event_fixture_setup, test_event, event_fixture_teardown); g_test_add_func("/test-command/print", test_print); + g_test_add_func("/test-command/uri", test_uri); g_test_add_func("/test-command/scroll", test_scroll); g_test_add_func("/test-command/toggle-status", test_toggle_status); g_test_add_func("/test-command/sync-sh", test_sync_sh); @@ -329,7 +335,7 @@ main (int argc, char *argv[]) { uzbl.state.config_file = "/tmp/uzbl-config"; uzbl.comm.fifo_path = "/tmp/some-nonexistant-fifo"; uzbl.comm.socket_path = "/tmp/some-nonexistant-socket"; - uzbl.state.uri = "http://example.org/"; + uzbl.state.uri = g_strdup("http://example.org/"); uzbl.gui.main_title = "Example.Org"; uzbl.state.instance_name = INSTANCE_NAME; -- cgit v1.2.3 From 16db5cab90d124a755cfba4644783a28d01fcf64 Mon Sep 17 00:00:00 2001 From: Felix Herrmann Date: Mon, 21 Feb 2011 00:47:28 +0100 Subject: fix memory leak in parse_command_parts --- src/uzbl-core.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 779f378..e565b14 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1161,8 +1161,10 @@ parse_command_parts(const gchar *line, GArray *a) { CommandInfo *c = NULL; gchar *exp_line = expand(line, 0); - if(exp_line[0] == '\0') + if(exp_line[0] == '\0') { + g_free(exp_line); return NULL; + } /* separate the line into the command and its parameters */ gchar **tokens = g_strsplit(exp_line, " ", 2); -- cgit v1.2.3 From 60b27c0e224a1153f8cfd6be61524efcf655c3da Mon Sep 17 00:00:00 2001 From: Jake Probst Date: Sun, 20 Feb 2011 17:58:37 -0800 Subject: getting yelled at about memory leaks --- src/callbacks.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index b603ea0..37c22a6 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -940,14 +940,13 @@ run_menu_command(GtkWidget *menu, MenuItem *mi) { if (mi->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { gchar* uri; g_object_get(mi->hittest, "image-uri", &uri, NULL); - - gchar* cmd = g_malloc(strlen(uri) + strlen(mi->cmd) + 5); - g_sprintf(cmd, "%s %s", mi->cmd, uri); + gchar* cmd = g_strdup_printf("%s %s", mi->cmd, uri); parse_cmd_line(cmd, NULL); g_free(cmd); g_free(uri); + g_object_unref(mi->hittest); } else { parse_cmd_line(mi->cmd, NULL); -- cgit v1.2.3 From 6adefaba33cae17f59aecd078ac909d553af468a Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Mon, 21 Feb 2011 15:25:18 -0700 Subject: new escaped events require new scroll percentage binding --- examples/config/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/config/config b/examples/config/config index bc07b0c..d5555e0 100644 --- a/examples/config/config +++ b/examples/config/config @@ -85,7 +85,7 @@ set download_handler = sync_spawn @scripts_dir/download.sh #@on_event CONFIG_CHANGED print Config changed: %1 = %2 # Scroll percentage calculation -@on_event SCROLL_VERT set scroll_message = \@<(function(){var a='%1'.split(' ');var p='--';if(a[2]!=a[1]){p=(a[0]/(a[2]-a[3]));p=Math.round(10000*p)/100;};return p+'%';})()>\@ +@on_event SCROLL_VERT set scroll_message = \@<(function(){var p='--';if(%3!=%2){p=(%1/(%3-%4));p=Math.round(10000*p)/100;};return p+'%';})()>\@ # === Behaviour and appearance =============================================== -- cgit v1.2.3 From 050e1f793e3f266bbec8a1e886d2b47eb77c2a27 Mon Sep 17 00:00:00 2001 From: kongo2002 Date: Tue, 22 Feb 2011 20:49:08 +0100 Subject: 'iskeyword' should not be used like this --- extras/vim/syntax/uzbl.vim | 3 --- 1 file changed, 3 deletions(-) diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index bf7108c..ee69e18 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -25,9 +25,6 @@ elseif exists("b:current_syntax") finish endif -" Don't match keywords inside strings -setl iskeyword=!-~,192-255 - syn keyword uzblKeyword back forward scroll reload reload_ign_cache stop syn keyword uzblKeyword zoom_in zoom_out toggle_zoom_type uri script syn keyword uzblKeyword toggle_status spawn sync_spawn sync_sh sync_spawn_exec -- cgit v1.2.3 From 9bcb10bb282dd23eaab62ea43b40b7eec921eb52 Mon Sep 17 00:00:00 2001 From: kongo2002 Date: Tue, 22 Feb 2011 20:52:28 +0100 Subject: modify js/sh keyword matches --- extras/vim/syntax/uzbl.vim | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index ee69e18..4e50be2 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -34,7 +34,11 @@ syn keyword uzblKeyword request menu_add menu_link_add menu_image_add syn keyword uzblKeyword menu_editable_add menu_separator menu_link_separator syn keyword uzblKeyword menu_image_separator menu_editable_separator syn keyword uzblKeyword menu_remove menu_link_remove menu_image_remove -syn keyword uzblKeyword menu_editable_remove hardcopy include js sh +syn keyword uzblKeyword menu_editable_remove hardcopy include + +" Match 'js' and 'sh' only without a dot in front +syn match uzblKeyword /\.\@ Date: Tue, 22 Feb 2011 20:54:24 +0100 Subject: change syntax file maintainer --- extras/vim/syntax/uzbl.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index 4e50be2..6163fbc 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -1,7 +1,7 @@ " Vim syntax file " Language: Uzbl config syntax -" Maintainer: Mason Larobina -" Contributors: Gregor Uhlenheuer (kongo2002) +" Maintainer: Gregor Uhlenheuer (kongo2002) +" Contributors: Mason Larobina " Pawel Tomak (grodzik) " Version: 0.1 " -- cgit v1.2.3 From 4d541ca2f0c52cd3368facf0ee28ee0060dd44ab Mon Sep 17 00:00:00 2001 From: kongo2002 Date: Tue, 22 Feb 2011 20:58:41 +0100 Subject: improve sh/js keyword matches --- extras/vim/syntax/uzbl.vim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/vim/syntax/uzbl.vim b/extras/vim/syntax/uzbl.vim index 6163fbc..1a4172b 100644 --- a/extras/vim/syntax/uzbl.vim +++ b/extras/vim/syntax/uzbl.vim @@ -37,8 +37,8 @@ syn keyword uzblKeyword menu_remove menu_link_remove menu_image_remove syn keyword uzblKeyword menu_editable_remove hardcopy include " Match 'js' and 'sh' only without a dot in front -syn match uzblKeyword /\.\@ Date: Fri, 25 Feb 2011 13:47:21 -0700 Subject: add current_encoding variable --- README | 1 + src/callbacks.c | 7 +++++++ src/callbacks.h | 3 +++ src/uzbl-core.c | 1 + src/uzbl-core.h | 1 + 5 files changed, 13 insertions(+) diff --git a/README b/README index d20cbd2..3ac9a28 100644 --- a/README +++ b/README @@ -356,6 +356,7 @@ file). stylesheet. * `resizable_text_areas`: Whether text areas can be resized (default 0). * `default_encoding`: The default text encoding (default "iso-8859-1"). +* `current_encoding`: This can be set to force a text encoding. * `enforce_96_dpi`: Enforce a resolution of 96 DPI (default 1). * `caret_browsing`: Whether the caret is enabled in the text portion of pages (default 0). diff --git a/src/callbacks.c b/src/callbacks.c index d315a9e..470e8dd 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -290,6 +290,13 @@ cmd_caret_browsing() { uzbl.behave.caret_browsing, NULL); } +void +set_current_encoding() { + webkit_web_view_set_custom_encoding(uzbl.gui.web_view, + uzbl.behave.current_encoding); +} + + void cmd_fifo_dir() { uzbl.behave.fifo_dir = init_fifo(uzbl.behave.fifo_dir); diff --git a/src/callbacks.h b/src/callbacks.h index 13cb83d..ab0c1df 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -109,6 +109,9 @@ cmd_resizable_txt(); void cmd_default_encoding(); +void +set_current_encoding(); + void cmd_enforce_96dpi(); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 638dd1f..a7f418c 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -131,6 +131,7 @@ const struct var_name_to_ptr_t { { "stylesheet_uri", PTR_V_STR(uzbl.behave.style_uri, 1, cmd_style_uri)}, { "resizable_text_areas", PTR_V_INT(uzbl.behave.resizable_txt, 1, cmd_resizable_txt)}, { "default_encoding", PTR_V_STR(uzbl.behave.default_encoding, 1, cmd_default_encoding)}, + { "current_encoding", PTR_V_STR(uzbl.behave.current_encoding, 1, set_current_encoding)}, { "enforce_96_dpi", PTR_V_INT(uzbl.behave.enforce_96dpi, 1, cmd_enforce_96dpi)}, { "caret_browsing", PTR_V_INT(uzbl.behave.caret_browsing, 1, cmd_caret_browsing)}, { "scrollbars_visible", PTR_V_INT(uzbl.gui.scrollbars_visible, 1, cmd_scrollbars_visibility)}, diff --git a/src/uzbl-core.h b/src/uzbl-core.h index 1285e3a..a4e055f 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -187,6 +187,7 @@ typedef struct { gchar* style_uri; guint resizable_txt; gchar* default_encoding; + gchar* current_encoding; guint enforce_96dpi; gchar *inject_html; guint caret_browsing; -- cgit v1.2.3 From 4bb757e944c074ab4969a859a67bc33b4b9698e0 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sat, 26 Feb 2011 08:26:31 -0700 Subject: check that 'result' is set in eval_js before assigning anything to it --- src/uzbl-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index a7f418c..bc75d87 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -763,7 +763,7 @@ eval_js(WebKitWebView * web_view, gchar *script, GString *result, const char *fi js_script = JSStringCreateWithUTF8CString(script); js_file = JSStringCreateWithUTF8CString(file); js_result = JSEvaluateScript(context, js_script, globalobject, js_file, 0, &js_exc); - if (js_result && !JSValueIsUndefined(context, js_result)) { + if (result && js_result && !JSValueIsUndefined(context, js_result)) { js_result_string = JSValueToStringCopy(context, js_result, NULL); js_result_size = JSStringGetMaximumUTF8CStringSize(js_result_string); -- cgit v1.2.3 From 80fda6e7880e598be9f7e7425e66c7b7eaa04e2a Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 26 Feb 2011 23:44:28 +0100 Subject: replace follow.js with taylanUBs version --- examples/data/scripts/follow.js | 282 +++++++++++++++++++--------------------- 1 file changed, 131 insertions(+), 151 deletions(-) diff --git a/examples/data/scripts/follow.js b/examples/data/scripts/follow.js index d995696..b0c4643 100644 --- a/examples/data/scripts/follow.js +++ b/examples/data/scripts/follow.js @@ -1,43 +1,47 @@ /* This is the basic linkfollowing script. * Its pretty stable, and you configure which keys to use for hinting * - * TODO: Some pages mess around a lot with the zIndex which - * lets some hints in the background. - * TODO: Some positions are not calculated correctly (mostly - * because of uber-fancy-designed-webpages. Basic HTML and CSS - * works good - * TODO: Still some links can't be followed/unexpected things - * happen. Blame some freaky webdesigners ;) + * TODO: + * Some pages mess around a lot with the zIndex which + * lets some hints in the background. + * Some positions are not calculated correctly (mostly + * because of uber-fancy-designed-webpages. Basic HTML and CSS + * works good + * Still some links can't be followed/unexpected things + * happen. Blame some freaky webdesigners ;) */ -//Just some shortcuts and globals -var uzblid = 'uzbl_link_hint'; -var uzbldivid = uzblid + '_div_container'; -var doc = document; -var win = window; -var links = document.links; -var forms = document.forms; -//Make onlick-links "clickable" -try { - HTMLElement.prototype.click = function() { - if (typeof this.onclick == 'function') { - this.onclick({ - type: 'click' - }); +uzbl.follow = function() { + + // Export + charset = arguments[0] + keypress = arguments[1] + newwindow = arguments[2] + + // Some shortcuts and globals + uzblid = 'uzbl_link_hint'; + uzbldivid = uzblid + '_div_container'; + doc = document; + win = window; + links = doc.links; + forms = doc.forms; + + // Make onclick-links "clickable" + try { + HTMLElement.prototype.click = function() { + if (typeof this.onclick == 'function') { + this.onclick({ type: 'click' }); + } } - }; -} catch(e) {} -//Catch the ESC keypress to stop linkfollowing -function keyPressHandler(e) { - var kC = window.event ? event.keyCode: e.keyCode; - var Esc = window.event ? 27 : e.DOM_VK_ESCAPE; - if (kC == Esc) { - removeAllHints(); - } + } catch(e) {} + + arguments.callee.followLinks(keypress); + } -//Calculate element position to draw the hint -//Pretty accurate but on fails in some very fancy cases -function elementPosition(el) { + +// Calculate element position to draw the hint +// Pretty accurate but fails in some very fancy cases +uzbl.follow.elementPosition = function(el) { var up = el.offsetTop; var left = el.offsetLeft; var width = el.offsetWidth; @@ -49,171 +53,155 @@ function elementPosition(el) { } return [up, left, width, height]; } -//Calculate if an element is visible -function isVisible(el) { - if (el == doc) { - return true; - } - if (!el) { - return false; - } - if (!el.parentNode) { - return false; - } + +// Calculate if an element is visible +uzbl.follow.isVisible = function(el) { + if (el == doc) return true; + if (!el) return false; + if (!el.parentNode) return false; + if (el.style) { - if (el.style.display == 'none') { - return false; - } - if (el.style.visibility == 'hidden') { - return false; - } + if (el.style.display == 'none') return false; + if (el.style.visibility == 'hidden') return false; } - return isVisible(el.parentNode); + return this.isVisible(el.parentNode); } -//Calculate if an element is on the viewport. -function elementInViewport(el) { - offset = elementPosition(el); + +// Calculate if an element is on the viewport. +uzbl.follow.elementInViewport = function(el) { + offset = this.elementPosition(el); var up = offset[0]; var left = offset[1]; var width = offset[2]; var height = offset[3]; return up < window.pageYOffset + window.innerHeight && left < window.pageXOffset + window.innerWidth && (up + height) > window.pageYOffset && (left + width) > window.pageXOffset; } -//Removes all hints/leftovers that might be generated -//by this script. -function removeAllHints() { + +// Removes all hints/leftovers that might be generated +// by this script. +uzbl.follow.removeAllHints = function() { var elements = doc.getElementById(uzbldivid); - if (elements) { - elements.parentNode.removeChild(elements); - } + if (elements) elements.parentNode.removeChild(elements); } -//Generate a hint for an element with the given label -//Here you can play around with the style of the hints! -function generateHint(el, label) { - var pos = elementPosition(el); + +// Generate a hint for an element with the given label +// Here you can play around with the style of the hints! +uzbl.follow.generateHint = function(el, label) { + var pos = this.elementPosition(el); var hint = doc.createElement('div'); hint.setAttribute('name', uzblid); hint.innerText = label; hint.style.display = 'inline'; - hint.style.backgroundColor = '#B9FF00'; - hint.style.border = '2px solid #4A6600'; + if (newwindow) hint.style.backgroundColor = '#ffff00'; + else hint.style.backgroundColor = '#aaff00'; + hint.style.border = '2px solid #556600'; hint.style.color = 'black'; + hint.style.fontFamily = 'Verdana'; hint.style.fontSize = '9px'; hint.style.fontWeight = 'bold'; + hint.style.fontVariant = 'normal'; hint.style.lineHeight = '9px'; hint.style.margin = '0px'; hint.style.width = 'auto'; // fix broken rendering on w3schools.com hint.style.padding = '1px'; hint.style.position = 'absolute'; hint.style.zIndex = '1000'; - // hint.style.textTransform = 'uppercase'; hint.style.left = pos[1] + 'px'; hint.style.top = pos[0] + 'px'; - // var img = el.getElementsByTagName('img'); - // if (img.length > 0) { - // hint.style.top = pos[1] + img[0].height / 2 - 6 + 'px'; - // } hint.style.textDecoration = 'none'; - // hint.style.webkitBorderRadius = '6px'; // slow - // Play around with this, pretty funny things to do :) - // hint.style.webkitTransform = 'scale(1) rotate(0deg) translate(-6px,-5px)'; + hint.style.webkitTransform = 'translate(-5px,-5px)'; return hint; } -// Here we choose what to do with an element that the user has selected. -// Form elements get selected and/or focussed, and links and buttons are -// clicked. This function returns "XXXRESET_MODEXXX" to indicate that uzbl -// should be reset to command mode with an empty keycmd, or -// "XXX_EMIT_FORM_ACTIVEXXX" to indicate that uzbl should be set to insert mode. -function clickElem(item) { - removeAllHints(); +// Here we choose what to do with an element if we +// want to "follow" it. On form elements we "select" +// or pass the focus, on links we try to perform a click, +// but at least set the href of the link. (needs some improvements) +uzbl.follow.clickElem = function(item) { + this.removeAllHints(); if (item) { - var name = item.tagName; - if (name == 'BUTTON') { - item.click(); - return "XXXRESET_MODEXXX"; - } else if (name == 'INPUT') { - var type = item.type.toUpperCase(); - if (type == 'TEXT' || type == 'SEARCH' || type == 'PASSWORD') { + if (newwindow && item.tagName == 'A') window.open(item.href); + else { + var name = item.tagName; + if (name == 'A') { + item.click(); + window.location = item.href; + } else if (name == 'INPUT') { + var type = item.getAttribute('type').toUpperCase(); + if (type == 'TEXT' || type == 'FILE' || type == 'PASSWORD') { + item.focus(); + item.select(); + } else { + item.click(); + } + } else if (name == 'TEXTAREA' || name == 'SELECT') { item.focus(); item.select(); - return "XXXEMIT_FORM_ACTIVEXXX"; } else { item.click(); - return "XXXRESET_MODEXXX"; + window.location = item.href; } - } else if (name == 'TEXTAREA' || name == 'SELECT') { - item.focus(); - item.select(); - return "XXXEMIT_FORM_ACTIVEXXX"; - } else { - item.click(); - window.location = item.href; - return "XXXRESET_MODEXXX"; } } } -//Returns a list of all links (in this version -//just the elements itself, but in other versions, we -//add the label here. -function addLinks() { + +// Returns a list of all links (in this version +// just the elements itself, but in other versions, we +// add the label here. +uzbl.follow.addLinks = function() { res = [[], []]; for (var l = 0; l < links.length; l++) { var li = links[l]; - if (isVisible(li) && elementInViewport(li)) { - res[0].push(li); - } + if (this.isVisible(li) && this.elementInViewport(li)) res[0].push(li); } return res; } -//Same as above, just for the form elements -function addFormElems() { + +// Same as above, just for the form elements +uzbl.follow.addFormElems = function() { res = [[], []]; for (var f = 0; f < forms.length; f++) { for (var e = 0; e < forms[f].elements.length; e++) { var el = forms[f].elements[e]; - if (el && ['INPUT', 'TEXTAREA', 'SELECT', 'BUTTON'].indexOf(el.tagName) + 1 && isVisible(el) && elementInViewport(el)) { - res[0].push(el); - } + if (el && ['INPUT', 'TEXTAREA', 'SELECT'].indexOf(el.tagName) + 1 && this.isVisible(el) && this.elementInViewport(el)) res[0].push(el); } } return res; } -//Draw all hints for all elements passed. "len" is for -//the number of chars we should use to avoid collisions -function reDrawHints(elems, chars) { - removeAllHints(); + +// Draw all hints for all elements passed. "len" is for +// the number of chars we should use to avoid collisions +uzbl.follow.reDrawHints = function(elems, chars) { + this.removeAllHints(); var hintdiv = doc.createElement('div'); hintdiv.setAttribute('id', uzbldivid); for (var i = 0; i < elems[0].length; i++) { if (elems[0][i]) { var label = elems[1][i].substring(chars); - var h = generateHint(elems[0][i], label); + var h = this.generateHint(elems[0][i], label); hintdiv.appendChild(h); } } - if (document.body) { - document.body.appendChild(hintdiv); - } + if (document.body) document.body.appendChild(hintdiv); } + // pass: number of keys // returns: key length -function labelLength(n) { +uzbl.follow.labelLength = function(n) { var oldn = n; var keylen = 0; - if(n < 2) { - return 1; - } - n -= 1; // our highest key will be n-1 + if(n < 2) return 1; + n -= 1; // Our highest key will be n-1 while(n) { keylen += 1; n = Math.floor(n / charset.length); } return keylen; } + // pass: number // returns: label -function intToLabel(n) { +uzbl.follow.intToLabel = function(n) { var label = ''; do { label = charset.charAt(n % charset.length) + label; @@ -221,9 +209,10 @@ function intToLabel(n) { } while(n); return label; } + // pass: label // returns: number -function labelToInt(label) { +uzbl.follow.labelToInt = function(label) { var n = 0; var i; for(i = 0; i < label.length; ++i) { @@ -232,44 +221,35 @@ function labelToInt(label) { } return n; } -//Put it all together -function followLinks(follow) { - // if(follow.charAt(0) == 'l') { - // follow = follow.substr(1); - // charset = 'thsnlrcgfdbmwvz-/'; - // } + +// Put it all together +uzbl.follow.followLinks = function(follow) { + //if(follow.charAt(0) == 'l') { + // follow = follow.substr(1); + // charset = 'thsnlrcgfdbmwvz-/'; + //} var s = follow.split(''); - var linknr = labelToInt(follow); + var linknr = this.labelToInt(follow); if (document.body) document.body.setAttribute('onkeyup', 'keyPressHandler(event)'); - var linkelems = addLinks(); - var formelems = addFormElems(); + var linkelems = this.addLinks(); + var formelems = this.addFormElems(); var elems = [linkelems[0].concat(formelems[0]), linkelems[1].concat(formelems[1])]; - var len = labelLength(elems[0].length); + var len = this.labelLength(elems[0].length); var oldDiv = doc.getElementById(uzbldivid); var leftover = [[], []]; - if (s.length == len && linknr < elems[0].length && linknr >= 0) { - return clickElem(elems[0][linknr]); - } else { + if (s.length == len && linknr < elems[0].length && linknr >= 0) this.clickElem(elems[0][linknr]); + else { for (var j = 0; j < elems[0].length; j++) { var b = true; - var label = intToLabel(j); + var label = this.intToLabel(j); var n = label.length; - for (n; n < len; n++) { - label = charset.charAt(0) + label; - } - for (var k = 0; k < s.length; k++) { - b = b && label.charAt(k) == s[k]; - } + for (n; n < len; n++) label = charset.charAt(0) + label; + for (var k = 0; k < s.length; k++) b = b && label.charAt(k) == s[k]; if (b) { leftover[0].push(elems[0][j]); leftover[1].push(label); } } - reDrawHints(leftover, s.length); + this.reDrawHints(leftover, s.length); } } - -//Parse input: first argument is follow keys, second is user input. -var args = '%s'.split(' '); -var charset = args[0]; -followLinks(args[1]); -- cgit v1.2.3 From d86a69f6a105f611e49ecb10d206933cfdd7f90a Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 26 Feb 2011 23:56:20 +0100 Subject: bring back mode change hints in follow.js --- examples/data/scripts/follow.js | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/examples/data/scripts/follow.js b/examples/data/scripts/follow.js index b0c4643..2976834 100644 --- a/examples/data/scripts/follow.js +++ b/examples/data/scripts/follow.js @@ -35,8 +35,7 @@ uzbl.follow = function() { } } catch(e) {} - arguments.callee.followLinks(keypress); - + return arguments.callee.followLinks(keypress); } // Calculate element position to draw the hint @@ -120,26 +119,34 @@ uzbl.follow.generateHint = function(el, label) { uzbl.follow.clickElem = function(item) { this.removeAllHints(); if (item) { - if (newwindow && item.tagName == 'A') window.open(item.href); + if (newwindow && item.tagName == 'A') { + window.open(item.href); + return "XXXRESET_MODEXXX" + } else { var name = item.tagName; if (name == 'A') { item.click(); window.location = item.href; + return "XXXRESET_MODEXXX"; } else if (name == 'INPUT') { var type = item.getAttribute('type').toUpperCase(); if (type == 'TEXT' || type == 'FILE' || type == 'PASSWORD') { item.focus(); item.select(); + return "XXXEMIT_FORM_ACTIVEXXX"; } else { item.click(); + return "XXXRESET_MODEXXX"; } } else if (name == 'TEXTAREA' || name == 'SELECT') { item.focus(); item.select(); + return "XXXEMIT_FORM_ACTIVEXXX"; } else { item.click(); window.location = item.href; + return "XXXRESET_MODEXXX"; } } } @@ -237,19 +244,19 @@ uzbl.follow.followLinks = function(follow) { var len = this.labelLength(elems[0].length); var oldDiv = doc.getElementById(uzbldivid); var leftover = [[], []]; - if (s.length == len && linknr < elems[0].length && linknr >= 0) this.clickElem(elems[0][linknr]); - else { - for (var j = 0; j < elems[0].length; j++) { - var b = true; - var label = this.intToLabel(j); - var n = label.length; - for (n; n < len; n++) label = charset.charAt(0) + label; - for (var k = 0; k < s.length; k++) b = b && label.charAt(k) == s[k]; - if (b) { - leftover[0].push(elems[0][j]); - leftover[1].push(label); - } + if (s.length == len && linknr < elems[0].length && linknr >= 0) + return this.clickElem(elems[0][linknr]); + + for (var j = 0; j < elems[0].length; j++) { + var b = true; + var label = this.intToLabel(j); + var n = label.length; + for (n; n < len; n++) label = charset.charAt(0) + label; + for (var k = 0; k < s.length; k++) b = b && label.charAt(k) == s[k]; + if (b) { + leftover[0].push(elems[0][j]); + leftover[1].push(label); } - this.reDrawHints(leftover, s.length); } + this.reDrawHints(leftover, s.length); } -- cgit v1.2.3 From 1197e8ddbc8348e9437ada42b35c72f38d4698ce Mon Sep 17 00:00:00 2001 From: keis Date: Sat, 26 Feb 2011 23:56:45 +0100 Subject: update config and follow.sh to use new follow.js --- examples/config/config | 4 +++- examples/data/scripts/follow.sh | 20 +++++--------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/examples/config/config b/examples/config/config index ab690e0..5c00fb5 100644 --- a/examples/config/config +++ b/examples/config/config @@ -72,6 +72,7 @@ set download_handler = sync_spawn @scripts_dir/download.sh # add some javascript to the page for other 'js' and 'script' commands to access later. @on_event LOAD_COMMIT js uzbl = {}; @on_event LOAD_COMMIT script @scripts_dir/formfiller.js +@on_event LOAD_COMMIT script @scripts_dir/follow.js # Userscripts/per-site-settings. See the script and the example configuration for details #@on_event LOAD_COMMIT spawn @scripts_dir/per-site-settings.py @data_home/uzbl/per-site-settings @@ -327,7 +328,8 @@ set follow_hint_keys = 0123456789 #set follow_hint_keys = qwerty #set follow_hint_keys = asdfghjkl; #set follow_hint_keys = thsnd-rcgmvwb/;789aefijkopquxyz234 -@cbind fl* = spawn @scripts_dir/follow.sh "%s" +@cbind fl* = spawn @scripts_dir/follow.sh \@< uzbl.follow("\@follow_hint_keys", "%s", 0) >\@ +@cbind Fl* = spawn @scripts_dir/follow.sh \@< uzbl.follow("\@follow_hint_keys", "%s", 1) >\@ @cbind gi = spawn @scripts_dir/go_input.sh # Form filler binds diff --git a/examples/data/scripts/follow.sh b/examples/data/scripts/follow.sh index d7fe117..1f8947d 100755 --- a/examples/data/scripts/follow.sh +++ b/examples/data/scripts/follow.sh @@ -1,21 +1,11 @@ #!/bin/sh +# This scripts acts on the return value of followLinks in follow.js -# This script is just a wrapper around follow.js that lets us change uzbl's mode -# after a link is selected. - -# if socat is installed then we can change Uzbl's input mode once a link is -# selected; otherwise we just select a link. -if ! which socat >/dev/null 2>&1; then - echo 'script @scripts_dir/follow.js "@{follow_hint_keys} '$1'"' > "$UZBL_FIFO" - exit -fi - -result=$(echo 'script @scripts_dir/follow.js "@{follow_hint_keys} '$1'"' | socat - unix-connect:"$UZBL_SOCKET") -case $result in - *XXXEMIT_FORM_ACTIVEXXX*) +case "$1" in + XXXEMIT_FORM_ACTIVEXXX) # a form element was selected - echo 'event FORM_ACTIVE' > "$UZBL_FIFO" ;; - *XXXRESET_MODEXXX*) + printf 'event FORM_ACTIVE\nevent KEYCMD_CLEAR\n' > "$UZBL_FIFO" ;; + XXXRESET_MODEXXX) # a link was selected, reset uzbl's input mode printf 'set mode=\nevent KEYCMD_CLEAR\n' > "$UZBL_FIFO" ;; esac -- cgit v1.2.3 From e44414affde4e5497386ce398cc2c40356c4e466 Mon Sep 17 00:00:00 2001 From: keis Date: Mon, 28 Feb 2011 22:03:26 +0100 Subject: add clear_cookies command --- README | 2 ++ src/uzbl-core.c | 15 ++++++++++++++- src/uzbl-core.h | 4 +--- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/README b/README index 3ac9a28..6709bf5 100644 --- a/README +++ b/README @@ -260,6 +260,8 @@ The following commands are recognized: * 'delete_cookie [ ]` - Deletes a matching cookie from the cookie jar. scheme and expire time is currently not considered when matching. +* 'clear_cookies` + - Clears all cookies from the cookie jar ### VARIABLES AND CONSTANTS diff --git a/src/uzbl-core.c b/src/uzbl-core.c index bc75d87..3303797 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -551,7 +551,8 @@ CommandInfo cmdlist[] = { "include", include, TRUE }, { "show_inspector", show_inspector, 0 }, { "add_cookie", add_cookie, 0 }, - { "delete_cookie", delete_cookie, 0 } + { "delete_cookie", delete_cookie, 0 }, + { "clear_cookies", clear_cookies, 0 } }; void @@ -725,6 +726,18 @@ delete_cookie(WebKitWebView *page, GArray *argv, GString *result) { uzbl.net.soup_cookie_jar->in_manual_add = 0; } + +void +clear_cookies(WebKitWebView *page, GArray *argv, GString *result) { + (void) page; (void) argv; (void) result; + + // Replace the current cookie jar with a new empty jar + soup_session_remove_feature (uzbl.net.soup_session, uzbl.net.soup_cookie_jar); + g_object_unref (G_OBJECT (uzbl.net.soup_cookie_jar)); + uzbl.net.soup_cookie_jar = uzbl_cookie_jar_new (); + soup_session_add_feature(uzbl.net.soup_session, uzbl.net.soup_cookie_jar); +} + void act_dump_config() { dump_config(); diff --git a/src/uzbl-core.h b/src/uzbl-core.h index a4e055f..56f4fac 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -315,9 +315,6 @@ void handle_authentication (SoupSession *session, SoupAuth *auth, gboolean retrying, gpointer user_data); -void handle_cookies (SoupSession *session, - SoupMessage *msg, - gpointer user_data); gboolean valid_name(const gchar* name); void set_var(WebKitWebView *page, GArray *argv, GString *result); void act_dump_config(); @@ -339,6 +336,7 @@ void include(WebKitWebView *page, GArray *argv, GString *result); void show_inspector(WebKitWebView *page, GArray *argv, GString *result); void add_cookie(WebKitWebView *page, GArray *argv, GString *result); void delete_cookie(WebKitWebView *page, GArray *argv, GString *result); +void clear_cookies(WebKitWebView *pag, GArray *argv, GString *result); void builtins(); typedef void (*Command)(WebKitWebView*, GArray *argv, GString *result); -- cgit v1.2.3 From 867c257b09b9c0f2ebe9b748ebdeffa355ef4711 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sat, 5 Mar 2011 10:38:59 -0700 Subject: fix a build warning --- src/callbacks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/callbacks.c b/src/callbacks.c index 470e8dd..cb9b492 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -1007,7 +1007,7 @@ populate_popup_cb(WebKitWebView *v, GtkMenu *m, void *c) { if (mi->context & WEBKIT_HIT_TEST_RESULT_CONTEXT_IMAGE) { GdkEventButton ev; gint x, y; - gdk_window_get_pointer(gtk_widget_get_window(v), &x, &y, NULL); + gdk_window_get_pointer(gtk_widget_get_window(GTK_WIDGET(v)), &x, &y, NULL); ev.x = x; ev.y = y; mi->hittest = webkit_web_view_get_hit_test_result(v, &ev); -- cgit v1.2.3 From 5bdc30a7ff4d18450eacd0d01860f707a56689ae Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sat, 5 Mar 2011 10:39:51 -0700 Subject: change @uri when the fragment identifier changes --- src/callbacks.c | 45 +++++++++++++++++++++++---------------------- src/callbacks.h | 3 +++ src/uzbl-core.c | 2 +- 3 files changed, 27 insertions(+), 23 deletions(-) diff --git a/src/callbacks.c b/src/callbacks.c index cb9b492..3a544a1 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -455,29 +455,44 @@ void load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { (void) param_spec; - WebKitWebFrame *frame = webkit_web_view_get_main_frame(web_view); WebKitLoadStatus status = webkit_web_view_get_load_status(web_view); switch(status) { case WEBKIT_LOAD_PROVISIONAL: - send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri ? uzbl.state.uri : "", NULL); + send_event(LOAD_START, NULL, TYPE_STR, uzbl.state.uri ? uzbl.state.uri : "", NULL); break; case WEBKIT_LOAD_COMMITTED: - g_free (uzbl.state.uri); - GString* newuri = g_string_new (webkit_web_frame_get_uri (frame)); - uzbl.state.uri = g_string_free (newuri, FALSE); - g_setenv("UZBL_URI", uzbl.state.uri, TRUE); - + frame = webkit_web_view_get_main_frame(web_view); send_event(LOAD_COMMIT, NULL, TYPE_STR, webkit_web_frame_get_uri (frame), NULL); break; case WEBKIT_LOAD_FINISHED: - send_event(LOAD_FINISH, NULL, TYPE_STR, webkit_web_frame_get_uri(frame), NULL); + send_event(LOAD_FINISH, NULL, TYPE_STR, uzbl.state.uri, NULL); break; case WEBKIT_LOAD_FIRST_VISUALLY_NON_EMPTY_LAYOUT: break; /* we don't do anything with this (yet) */ case WEBKIT_LOAD_FAILED: break; /* load_error_cb will handle this case */ } +} + +void +load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud) { + (void) page; (void) frame; (void) ud; + GError *err = web_err; + + send_event (LOAD_ERROR, NULL, + TYPE_STR, uri, + TYPE_INT, err->code, + TYPE_STR, err->message, + NULL); +} + +void +uri_change_cb (WebKitWebView *web_view, GParamSpec param_spec) { + (void) param_spec; + g_free (uzbl.state.uri); + g_object_get (web_view, "uri", &uzbl.state.uri, NULL); + g_setenv("UZBL_URI", uzbl.state.uri, TRUE); } void @@ -491,20 +506,6 @@ selection_changed_cb(WebKitWebView *webkitwebview, gpointer ud) { g_free(tmp); } -void -load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud) { - (void) page; - (void) frame; - (void) ud; - GError *err = web_err; - - send_event (LOAD_ERROR, NULL, - TYPE_STR, uri, - TYPE_INT, err->code, - TYPE_STR, err->message, - NULL); -} - void destroy_cb (GtkWidget* widget, gpointer data) { (void) widget; diff --git a/src/callbacks.h b/src/callbacks.h index ab0c1df..d34b9fa 100644 --- a/src/callbacks.h +++ b/src/callbacks.h @@ -160,6 +160,9 @@ load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec); void load_error_cb (WebKitWebView* page, WebKitWebFrame* frame, gchar *uri, gpointer web_err, gpointer ud); +void +uri_change_cb (WebKitWebView *web_view, GParamSpec param_spec); + void selection_changed_cb(WebKitWebView *webkitwebview, gpointer ud); diff --git a/src/uzbl-core.c b/src/uzbl-core.c index 31ed50d..d73fbdf 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1394,7 +1394,6 @@ update_title(void) { } } - void create_scrolled_win() { GUI* g = &uzbl.gui; @@ -1423,6 +1422,7 @@ create_scrolled_win() { "signal::selection-changed", (GCallback)selection_changed_cb, NULL, "signal::notify::progress", (GCallback)progress_change_cb, NULL, "signal::notify::load-status", (GCallback)load_status_change_cb, NULL, + "signal::notify::uri", (GCallback)uri_change_cb, NULL, "signal::load-error", (GCallback)load_error_cb, NULL, "signal::hovering-over-link", (GCallback)link_hover_cb, NULL, "signal::navigation-policy-decision-requested", (GCallback)navigation_decision_cb, NULL, -- cgit v1.2.3 From cefa7bb4a4e99e6fa7fd7ddcf7866ee60be50fc5 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sat, 5 Mar 2011 12:08:35 -0700 Subject: fix a build error i am a bad person who doesn't test my commits. --- src/callbacks.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/callbacks.c b/src/callbacks.c index 3a544a1..deda426 100644 --- a/src/callbacks.c +++ b/src/callbacks.c @@ -455,6 +455,7 @@ void load_status_change_cb (WebKitWebView* web_view, GParamSpec param_spec) { (void) param_spec; + WebKitWebFrame *frame; WebKitLoadStatus status = webkit_web_view_get_load_status(web_view); switch(status) { case WEBKIT_LOAD_PROVISIONAL: -- cgit v1.2.3 From 941b92e60d4f636e16ab0d3bd0814073b27a0642 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sun, 6 Mar 2011 02:40:35 -0700 Subject: frames-enabled follow.js --- examples/data/scripts/follow.js | 291 +++++++++++++++++++++------------------- 1 file changed, 153 insertions(+), 138 deletions(-) diff --git a/examples/data/scripts/follow.js b/examples/data/scripts/follow.js index 2976834..1551f1c 100644 --- a/examples/data/scripts/follow.js +++ b/examples/data/scripts/follow.js @@ -12,81 +12,101 @@ */ uzbl.follow = function() { - // Export - charset = arguments[0] - keypress = arguments[1] - newwindow = arguments[2] + charset = arguments[0]; + newwindow = arguments[2]; // Some shortcuts and globals uzblid = 'uzbl_link_hint'; uzbldivid = uzblid + '_div_container'; - doc = document; - win = window; - links = doc.links; - forms = doc.forms; - - // Make onclick-links "clickable" - try { - HTMLElement.prototype.click = function() { - if (typeof this.onclick == 'function') { - this.onclick({ type: 'click' }); - } - } - } catch(e) {} + var keypress = arguments[1]; return arguments.callee.followLinks(keypress); } +uzbl.follow.isFrame = function(el) { + return (el.tagName == "FRAME" || el.tagName == "IFRAME"); +} + +// find the document that the given element belongs to +uzbl.follow.getDocument = function(el) { + if (this.isFrame(el)) + return el.contentDocument; + + var doc = el; + while (doc.parentNode !== null) + doc = doc.parentNode; + return doc; +} + +// find all documents in the display, searching frames recursively +uzbl.follow.documents = function() { + return this.windows().map(function(w) { return w.document; }).filter(function(d) { return d != null; }); +} + +// find all windows in the display, searching for frames recursively +uzbl.follow.windows = function(w) { +  w = (typeof w == 'undefined') ? window.top : w; + + var wins = [w]; + var frames = w.frames; + for(var i = 0; i < frames.length; i++) + wins = wins.concat(uzbl.follow.windows(frames[i])); + return wins; +} + +// search all frames for elements matching the given CSS selector +uzbl.follow.query = function(selector) { + var res = []; + this.documents().forEach(function (doc) { + var set = doc.body.querySelectorAll(selector); + // convert the NodeList to an Array + set = Array.prototype.slice.call(set); + res = res.concat(set); + }); + return res; +} + // Calculate element position to draw the hint -// Pretty accurate but fails in some very fancy cases uzbl.follow.elementPosition = function(el) { - var up = el.offsetTop; - var left = el.offsetLeft; - var width = el.offsetWidth; - var height = el.offsetHeight; - while (el.offsetParent) { - el = el.offsetParent; - up += el.offsetTop; - left += el.offsetLeft; - } - return [up, left, width, height]; -} + var rect = el.getBoundingClientRect(); -// Calculate if an element is visible -uzbl.follow.isVisible = function(el) { - if (el == doc) return true; - if (!el) return false; - if (!el.parentNode) return false; + var left, up; - if (el.style) { - if (el.style.display == 'none') return false; - if (el.style.visibility == 'hidden') return false; + if (uzbl.follow.isFrame(el)) { + left = document.defaultView.scrollX; + up = document.defaultView.scrollY; + } else { + left = Math.max((rect.left + document.defaultView.scrollX), document.defaultView.scrollX); + up = Math.max((rect.top + document.defaultView.scrollY), document.defaultView.scrollY); } - return this.isVisible(el.parentNode); + + return [up, left, rect.width, rect.height]; } // Calculate if an element is on the viewport. uzbl.follow.elementInViewport = function(el) { - offset = this.elementPosition(el); - var up = offset[0]; - var left = offset[1]; - var width = offset[2]; + offset = uzbl.follow.elementPosition(el); + var up = offset[0]; + var left = offset[1]; + var width = offset[2]; var height = offset[3]; - return up < window.pageYOffset + window.innerHeight && left < window.pageXOffset + window.innerWidth && (up + height) > window.pageYOffset && (left + width) > window.pageXOffset; + return up < window.pageYOffset + window.innerHeight && + left < window.pageXOffset + window.innerWidth && + (up + height) > window.pageYOffset && + (left + width) > window.pageXOffset; } // Removes all hints/leftovers that might be generated // by this script. -uzbl.follow.removeAllHints = function() { +uzbl.follow.removeAllHints = function(doc) { var elements = doc.getElementById(uzbldivid); if (elements) elements.parentNode.removeChild(elements); } // Generate a hint for an element with the given label // Here you can play around with the style of the hints! -uzbl.follow.generateHint = function(el, label) { - var pos = this.elementPosition(el); +uzbl.follow.generateHint = function(doc, el, label, top, left) { var hint = doc.createElement('div'); hint.setAttribute('name', uzblid); hint.innerText = label; @@ -105,10 +125,10 @@ uzbl.follow.generateHint = function(el, label) { hint.style.padding = '1px'; hint.style.position = 'absolute'; hint.style.zIndex = '1000'; - hint.style.left = pos[1] + 'px'; - hint.style.top = pos[0] + 'px'; hint.style.textDecoration = 'none'; hint.style.webkitTransform = 'translate(-5px,-5px)'; + hint.style.top = top + 'px'; + hint.style.left = left + 'px'; return hint; } @@ -117,79 +137,53 @@ uzbl.follow.generateHint = function(el, label) { // or pass the focus, on links we try to perform a click, // but at least set the href of the link. (needs some improvements) uzbl.follow.clickElem = function(item) { - this.removeAllHints(); - if (item) { - if (newwindow && item.tagName == 'A') { - window.open(item.href); - return "XXXRESET_MODEXXX" - } - else { - var name = item.tagName; - if (name == 'A') { - item.click(); - window.location = item.href; - return "XXXRESET_MODEXXX"; - } else if (name == 'INPUT') { - var type = item.getAttribute('type').toUpperCase(); - if (type == 'TEXT' || type == 'FILE' || type == 'PASSWORD') { - item.focus(); - item.select(); - return "XXXEMIT_FORM_ACTIVEXXX"; - } else { - item.click(); - return "XXXRESET_MODEXXX"; - } - } else if (name == 'TEXTAREA' || name == 'SELECT') { - item.focus(); - item.select(); - return "XXXEMIT_FORM_ACTIVEXXX"; - } else { - item.click(); - window.location = item.href; - return "XXXRESET_MODEXXX"; - } - } - } -} + if(!item) return; + var name = item.tagName; -// Returns a list of all links (in this version -// just the elements itself, but in other versions, we -// add the label here. -uzbl.follow.addLinks = function() { - res = [[], []]; - for (var l = 0; l < links.length; l++) { - var li = links[l]; - if (this.isVisible(li) && this.elementInViewport(li)) res[0].push(li); - } - return res; -} - -// Same as above, just for the form elements -uzbl.follow.addFormElems = function() { - res = [[], []]; - for (var f = 0; f < forms.length; f++) { - for (var e = 0; e < forms[f].elements.length; e++) { - var el = forms[f].elements[e]; - if (el && ['INPUT', 'TEXTAREA', 'SELECT'].indexOf(el.tagName) + 1 && this.isVisible(el) && this.elementInViewport(el)) res[0].push(el); + if (name == 'INPUT') { + var type = item.getAttribute('type').toUpperCase(); + if (type == 'TEXT' || type == 'FILE' || type == 'PASSWORD') { + item.focus(); + item.select(); + return "XXXEMIT_FORM_ACTIVEXXX"; } + // otherwise fall through to a simulated mouseclick. + } else if (name == 'TEXTAREA' || name == 'SELECT') { + item.focus(); + item.select(); + return "XXXEMIT_FORM_ACTIVEXXX"; } - return res; + + // simulate a mouseclick to activate the element + var mouseEvent = document.createEvent("MouseEvent"); + mouseEvent.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null); + item.dispatchEvent(mouseEvent); + return "XXXRESET_MODEXXX"; } -// Draw all hints for all elements passed. "len" is for -// the number of chars we should use to avoid collisions +// Draw all hints for all elements passed. uzbl.follow.reDrawHints = function(elems, chars) { - this.removeAllHints(); - var hintdiv = doc.createElement('div'); - hintdiv.setAttribute('id', uzbldivid); - for (var i = 0; i < elems[0].length; i++) { - if (elems[0][i]) { - var label = elems[1][i].substring(chars); - var h = this.generateHint(elems[0][i], label); - hintdiv.appendChild(h); - } - } - if (document.body) document.body.appendChild(hintdiv); + var elements = elems.map(function(pair) { return pair[0] }); + var labels = elems.map(function(pair) { return pair[1].substring(chars) }); + // we have to calculate element positions before we modify the DOM + // otherwise the elementPosition call slows way down. + var positions = elements.map(uzbl.follow.elementPosition); + + this.documents().forEach(function(doc) { + uzbl.follow.removeAllHints(doc); + if (!doc.body) return; + doc.hintdiv = doc.createElement('div'); + doc.hintdiv.setAttribute('id', uzbldivid); + doc.body.appendChild(doc.hintdiv); + }); + + elements.forEach(function(el, i) { + var label = labels[i]; + var pos = positions[i]; + var doc = uzbl.follow.getDocument(el); + var h = uzbl.follow.generateHint(doc, el, label, pos[0], pos[1]); + doc.hintdiv.appendChild(h); + }); } // pass: number of keys @@ -221,8 +215,7 @@ uzbl.follow.intToLabel = function(n) { // returns: number uzbl.follow.labelToInt = function(label) { var n = 0; - var i; - for(i = 0; i < label.length; ++i) { + for(var i = 0; i < label.length; ++i) { n *= charset.length; n += charset.indexOf(label[i]); } @@ -231,32 +224,54 @@ uzbl.follow.labelToInt = function(label) { // Put it all together uzbl.follow.followLinks = function(follow) { - //if(follow.charAt(0) == 'l') { - // follow = follow.substr(1); - // charset = 'thsnlrcgfdbmwvz-/'; - //} var s = follow.split(''); var linknr = this.labelToInt(follow); - if (document.body) document.body.setAttribute('onkeyup', 'keyPressHandler(event)'); - var linkelems = this.addLinks(); - var formelems = this.addFormElems(); - var elems = [linkelems[0].concat(formelems[0]), linkelems[1].concat(formelems[1])]; - var len = this.labelLength(elems[0].length); - var oldDiv = doc.getElementById(uzbldivid); - var leftover = [[], []]; - if (s.length == len && linknr < elems[0].length && linknr >= 0) - return this.clickElem(elems[0][linknr]); - - for (var j = 0; j < elems[0].length; j++) { + + var followable = 'a, area, textarea, select, input:not([type=hidden]), button'; + var uri = 'a, area, frame, iframe'; + //var focusable = 'a, area, textarea, select, input:not([type=hidden]), button, frame, iframe, applet, object'; + //var desc = '*[title], img[alt], applet[alt], area[alt], input[alt]'; + //var image = 'img, input[type=image]'; + + if(newwindow) + var res = this.query(uri); + else + var res = this.query(followable); + + var elems = res.filter(uzbl.follow.elementInViewport); + var len = this.labelLength(elems.length); + + if (s.length == len && linknr < elems.length && linknr >= 0) { + // an element has been selected! + var el = elems[linknr]; + + // clear all of our hints + this.documents().forEach(uzbl.follow.removeAllHints); + + if (newwindow) { + // we're opening a new window using the URL attached to this element + var uri = el.src || el.href; + if(uri.match(/javascript:/)) return; + window.open(uri); + return "XXXRESET_MODEXXX" + } + + // we're just going to click the element + return this.clickElem(el); + } + + var leftover = []; + for (var j = 0; j < elems.length; j++) { var b = true; var label = this.intToLabel(j); var n = label.length; - for (n; n < len; n++) label = charset.charAt(0) + label; - for (var k = 0; k < s.length; k++) b = b && label.charAt(k) == s[k]; - if (b) { - leftover[0].push(elems[0][j]); - leftover[1].push(label); - } + for (n; n < len; n++) + label = charset.charAt(0) + label; + for (var k = 0; k < s.length; k++) + b = b && label.charAt(k) == s[k]; + if (b) + leftover.push([elems[j], label]); } + this.reDrawHints(leftover, s.length); } -- cgit v1.2.3 From bece24e3824d11c08fad9c6338f446ee29d4913f Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sun, 6 Mar 2011 03:06:26 -0700 Subject: do link hint styling in user stylesheet. --- examples/config/config | 3 +++ examples/data/scripts/follow.js | 30 ++++++------------------------ examples/data/style.css | 38 ++++++++++++++++++-------------------- 3 files changed, 27 insertions(+), 44 deletions(-) diff --git a/examples/config/config b/examples/config/config index 5c00fb5..bcd6d3e 100644 --- a/examples/config/config +++ b/examples/config/config @@ -94,6 +94,9 @@ set download_handler = sync_spawn @scripts_dir/download.sh # === Behaviour and appearance =============================================== +# Custom CSS can be defined here, including link follower hint styles +set stylesheet_uri = file://@data_home/uzbl/style.css + set show_status = 1 set status_top = 0 set status_background = #303030 diff --git a/examples/data/scripts/follow.js b/examples/data/scripts/follow.js index 1551f1c..2b9da59 100644 --- a/examples/data/scripts/follow.js +++ b/examples/data/scripts/follow.js @@ -1,5 +1,4 @@ /* This is the basic linkfollowing script. - * Its pretty stable, and you configure which keys to use for hinting * * TODO: * Some pages mess around a lot with the zIndex which @@ -11,15 +10,14 @@ * happen. Blame some freaky webdesigners ;) */ +// Globals +uzbldivid = 'uzbl_link_hints'; + uzbl.follow = function() { // Export charset = arguments[0]; newwindow = arguments[2]; - // Some shortcuts and globals - uzblid = 'uzbl_link_hint'; - uzbldivid = uzblid + '_div_container'; - var keypress = arguments[1]; return arguments.callee.followLinks(keypress); } @@ -107,26 +105,9 @@ uzbl.follow.removeAllHints = function(doc) { // Generate a hint for an element with the given label // Here you can play around with the style of the hints! uzbl.follow.generateHint = function(doc, el, label, top, left) { - var hint = doc.createElement('div'); - hint.setAttribute('name', uzblid); + var hint = doc.createElement('span'); hint.innerText = label; - hint.style.display = 'inline'; - if (newwindow) hint.style.backgroundColor = '#ffff00'; - else hint.style.backgroundColor = '#aaff00'; - hint.style.border = '2px solid #556600'; - hint.style.color = 'black'; - hint.style.fontFamily = 'Verdana'; - hint.style.fontSize = '9px'; - hint.style.fontWeight = 'bold'; - hint.style.fontVariant = 'normal'; - hint.style.lineHeight = '9px'; - hint.style.margin = '0px'; - hint.style.width = 'auto'; // fix broken rendering on w3schools.com - hint.style.padding = '1px'; hint.style.position = 'absolute'; - hint.style.zIndex = '1000'; - hint.style.textDecoration = 'none'; - hint.style.webkitTransform = 'translate(-5px,-5px)'; hint.style.top = top + 'px'; hint.style.left = left + 'px'; return hint; @@ -173,7 +154,8 @@ uzbl.follow.reDrawHints = function(elems, chars) { uzbl.follow.removeAllHints(doc); if (!doc.body) return; doc.hintdiv = doc.createElement('div'); - doc.hintdiv.setAttribute('id', uzbldivid); + doc.hintdiv.id = uzbldivid; + if(newwindow) doc.hintdiv.className = "new-window"; doc.body.appendChild(doc.hintdiv); }); diff --git a/examples/data/style.css b/examples/data/style.css index f9b111e..45bb56f 100644 --- a/examples/data/style.css +++ b/examples/data/style.css @@ -1,25 +1,23 @@ -.uzbl_highlight { background-color: yellow;} -.uzbl_h_first { background-color: lightgreen;} - -.uzbl_follow { border-style: dotted; - border-width: thin; +#uzbl_link_hints > span { + background-color: #aaff00; + color: black; + border: 2px solid #556600; + font-family: Verdana; + font-size: 9px; + font-weight: bold; + font-variant: normal; + line-height: 9px; + margin: 0px; + width: auto; /* fix broken rendering on w3schools.com */ + padding: 1px; + z-index: 1000; + text-decoration: none; + -webkit-transform: translate(-5px,-5px); } -#uzbl_hint > div { - display: inline; - border: 2px solid #4a6600; - background-color: #b9ff00; - color: black; - font-size: 9px; - font-weight: bold; - line-height: 9px; - margin: 0px; - padding: 0px; - position: absolute; - z-index: 1000; - -webkit-border-radius: 6px; - text-decoration: none; - -wekit-transform: scale(1) rotate(0deg) translate(-6px,-5px); +/* we can have different colours for different types of hints! */ +#uzbl_link_hints.new-window > span { + background-color: #ffff00; } /* vim:set et ts=4: */ -- cgit v1.2.3 From 4e702cd8f7b02174c2bd9d18d8b8b62715ffb066 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sun, 6 Mar 2011 08:56:17 -0700 Subject: remove unused variables from the UzblCore struct --- src/uzbl-core.h | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/src/uzbl-core.h b/src/uzbl-core.h index a4e055f..766fe56 100644 --- a/src/uzbl-core.h +++ b/src/uzbl-core.h @@ -165,7 +165,6 @@ typedef struct { gchar* cursive_font_family; gboolean forward_keys; - guint modmask; guint http_debug; gchar* shell_cmd; guint view_source; @@ -192,8 +191,6 @@ typedef struct { gchar *inject_html; guint caret_browsing; guint javascript_windows; - guint mode; - gchar* base_url; gboolean print_version; /* command list: (key)name -> (value)Command */ @@ -204,14 +201,6 @@ typedef struct { } Behaviour; -/* Javascript */ -typedef struct { - gboolean initialized; - JSClassDefinition classdef; - JSClassRef classref; -} Javascript; - - /* Static information */ typedef struct { int webkit_major; @@ -230,7 +219,6 @@ typedef struct { Network net; Behaviour behave; Communication comm; - Javascript js; Info info; Window xwin; -- cgit v1.2.3 From 3f4a22ab664d2da5a3d398d9cbf1131caf75f706 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sun, 6 Mar 2011 09:17:21 -0700 Subject: key_to_event: don't crash when gdk_keyval_name returns NULL --- src/events.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/events.c b/src/events.c index 174ff75..641409c 100644 --- a/src/events.c +++ b/src/events.c @@ -205,6 +205,7 @@ void key_to_event(guint keyval, gint mode) { gchar ucs[7]; gint ulen; + gchar *keyname; guint32 ukval = gdk_keyval_to_unicode(keyval); /* check for printable unicode char */ @@ -219,9 +220,9 @@ key_to_event(guint keyval, gint mode) { NULL, TYPE_FORMATTEDSTR, ucs, NULL); } /* send keysym for non-printable chars */ - else { + else if((keyname = gdk_keyval_name(keyval))){ send_event(mode == GDK_KEY_PRESS ? KEY_PRESS : KEY_RELEASE, - NULL, TYPE_NAME, gdk_keyval_name(keyval), NULL); + NULL, TYPE_NAME, keyname , NULL); } } -- cgit v1.2.3 From a0a11b1b1ad90a16641d0a87b0d43b1fabdabb08 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sun, 6 Mar 2011 09:28:07 -0700 Subject: follow.js: hint wrapped links on their left end, not the left end of the bounding rectangle --- examples/data/scripts/follow.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/examples/data/scripts/follow.js b/examples/data/scripts/follow.js index 2b9da59..536256b 100644 --- a/examples/data/scripts/follow.js +++ b/examples/data/scripts/follow.js @@ -67,19 +67,21 @@ uzbl.follow.query = function(selector) { // Calculate element position to draw the hint uzbl.follow.elementPosition = function(el) { - var rect = el.getBoundingClientRect(); - - var left, up; - - if (uzbl.follow.isFrame(el)) { - left = document.defaultView.scrollX; - up = document.defaultView.scrollY; - } else { - left = Math.max((rect.left + document.defaultView.scrollX), document.defaultView.scrollX); - up = Math.max((rect.top + document.defaultView.scrollY), document.defaultView.scrollY); + // el.getBoundingClientRect is another way to do this, but when a link is + // line-wrapped we want our hint at the left end of the link, not its + // bounding rectangle + var up = el.offsetTop; + var left = el.offsetLeft; + var width = el.offsetWidth; + var height = el.offsetHeight; + + while (el.offsetParent) { + el = el.offsetParent; + up += el.offsetTop; + left += el.offsetLeft; } - return [up, left, rect.width, rect.height]; + return [up, left, width, height]; } // Calculate if an element is on the viewport. -- cgit v1.2.3 From e4c7af276c9ad363f26d34a672508a7acf31dd79 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sun, 6 Mar 2011 09:38:09 -0700 Subject: tidy up link hinting CSS, add !important rules --- examples/data/style.css | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/examples/data/style.css b/examples/data/style.css index 45bb56f..ff055d1 100644 --- a/examples/data/style.css +++ b/examples/data/style.css @@ -1,23 +1,25 @@ #uzbl_link_hints > span { - background-color: #aaff00; - color: black; - border: 2px solid #556600; - font-family: Verdana; - font-size: 9px; - font-weight: bold; - font-variant: normal; - line-height: 9px; - margin: 0px; - width: auto; /* fix broken rendering on w3schools.com */ - padding: 1px; - z-index: 1000; - text-decoration: none; + z-index: 1000 !important; + + background-color: #aaff00 !important; + border: 2px solid #556600 !important; + margin: 0 !important; + padding: 1px !important; + + color: black !important; + font-size: 9px !important; + line-height: 9px !important; + font-weight: bold !important; + font-variant: normal !important; + text-decoration: none !important; + -webkit-transform: translate(-5px,-5px); + /* opacity: 0.7; */ } /* we can have different colours for different types of hints! */ #uzbl_link_hints.new-window > span { - background-color: #ffff00; + background-color: #ffff00 !important; } /* vim:set et ts=4: */ -- cgit v1.2.3 From 9eda8302a970790e984545fd7d8f8aa81d9c9e70 Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 10 Mar 2011 19:13:00 -0700 Subject: don't expose send_event_socket and send_event_fifo --- src/events.c | 2 +- src/events.h | 5 +---- src/io.c | 4 ++-- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/events.c b/src/events.c index 641409c..58dddfc 100644 --- a/src/events.c +++ b/src/events.c @@ -92,7 +92,7 @@ send_event_sockets(GPtrArray *sockets, GString *msg) { } } -static void +void replay_buffered_events() { guint i = 0; diff --git a/src/events.h b/src/events.h index 8e75097..bd519a6 100644 --- a/src/events.h +++ b/src/events.h @@ -33,10 +33,7 @@ void event_buffer_timeout(guint sec); void -send_event_socket(GString *msg); - -void -send_event_stdout(GString *msg); +replay_buffered_events(); void vsend_event(int type, const gchar *custom_event, va_list vargs); diff --git a/src/io.c b/src/io.c index b84780e..80a7337 100644 --- a/src/io.c +++ b/src/io.c @@ -216,8 +216,8 @@ init_connect_socket() { } /* replay buffered events */ - if(replay) - send_event_socket(NULL); + if(replay && uzbl.state.event_buffer) + replay_buffered_events(); } -- cgit v1.2.3 From cf922a2972ebc5cbda517542849f2c625b09601e Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 10 Mar 2011 19:20:30 -0700 Subject: fix a couple of calls to send_event --- src/inspector.c | 4 ++-- src/io.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/inspector.c b/src/inspector.c index de3dbcd..4c8c890 100644 --- a/src/inspector.c +++ b/src/inspector.c @@ -49,7 +49,7 @@ inspector_show_window_cb (WebKitWebInspector* inspector){ (void) inspector; gtk_widget_show(uzbl.gui.inspector_window); - send_event(WEBINSPECTOR, "open", NULL); + send_event(WEBINSPECTOR, NULL, TYPE_NAME, "open", NULL); return TRUE; } @@ -57,7 +57,7 @@ inspector_show_window_cb (WebKitWebInspector* inspector){ gboolean inspector_close_window_cb (WebKitWebInspector* inspector){ (void) inspector; - send_event(WEBINSPECTOR, "close", NULL); + send_event(WEBINSPECTOR, NULL, TYPE_NAME, "close", NULL); return TRUE; } diff --git a/src/io.c b/src/io.c index 1e85237..d9a2488 100644 --- a/src/io.c +++ b/src/io.c @@ -61,7 +61,7 @@ attach_fifo(gchar *path) { if (g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_fifo, NULL)) { if (uzbl.state.verbose) printf ("attach_fifo: created successfully as %s\n", path); - send_event(FIFO_SET, path, NULL); + send_event(FIFO_SET, NULL, TYPE_STR, path, NULL); uzbl.comm.fifo_path = path; g_setenv("UZBL_FIFO", uzbl.comm.fifo_path, TRUE); return TRUE; @@ -282,7 +282,7 @@ attach_socket(gchar *path, struct sockaddr_un *local) { if( (chan = g_io_channel_unix_new(sock)) ) { g_io_add_watch(chan, G_IO_IN|G_IO_HUP, (GIOFunc) control_socket, chan); uzbl.comm.socket_path = path; - send_event(SOCKET_SET, path, NULL); + send_event(SOCKET_SET, NULL, TYPE_STR, path, NULL); g_setenv("UZBL_SOCKET", uzbl.comm.socket_path, TRUE); return TRUE; } -- cgit v1.2.3 From 316d1c03cc7ec7b41d6222a6a723971523763cdf Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Thu, 10 Mar 2011 19:24:05 -0700 Subject: uzbl-tabbed: don't freak out if an invalid status_background colour is given --- examples/data/scripts/uzbl-tabbed | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/data/scripts/uzbl-tabbed b/examples/data/scripts/uzbl-tabbed index 1d64436..de71c2c 100755 --- a/examples/data/scripts/uzbl-tabbed +++ b/examples/data/scripts/uzbl-tabbed @@ -472,8 +472,11 @@ class UzblInstance: self.parent.update_gtk_tab_pos() elif var == "status_background": if config['status_background'].strip(): - col = gtk.gdk.color_parse(config['status_background']) - self.parent.ebox.modify_bg(gtk.STATE_NORMAL, col) + try: + col = gtk.gdk.color_parse(config['status_background']) + self.parent.ebox.modify_bg(gtk.STATE_NORMAL, col) + except ValueError: + pass # got an invalid colour, just ignore it elif var == "tab_titles" or var == "tab_indexes": for tab in self.parent.notebook: self.parent.tabs[tab].title_changed(True) -- cgit v1.2.3 From cbfe2c7d9f93429a97938d2427e56fc0f4eae56c Mon Sep 17 00:00:00 2001 From: Brendan Taylor Date: Sat, 12 Mar 2011 13:08:49 -0700 Subject: gtk3: don't render a useless window resizing grip --- src/uzbl-core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/uzbl-core.c b/src/uzbl-core.c index d73fbdf..b5cbf38 100644 --- a/src/uzbl-core.c +++ b/src/uzbl-core.c @@ -1478,6 +1478,10 @@ create_window() { gtk_widget_set_name (window, "Uzbl browser"); gtk_window_set_title(GTK_WINDOW(window), "Uzbl browser"); +#if GTK_CHECK_VERSION(3,0,0) + gtk_window_set_has_resize_grip (window, FALSE); +#endif + /* if the window has been made small, it shouldn't try to resize itself due * to a long statusbar. */ GdkGeometry hints; -- cgit v1.2.3