diff options
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/CMakeLists.txt | 12 | ||||
-rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/core/ephraim.erl | 6 | ||||
-rw-r--r-- | src/core/ephraim_gui.erl | 28 | ||||
-rwxr-xr-x | src/ephraim | 2 | ||||
-rw-r--r-- | src/gui/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/gui/CoreConnector.vala | 209 | ||||
-rw-r--r-- | src/gui/Ephraim.vala | 5 |
9 files changed, 145 insertions, 130 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ea896e..b9d5b81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ project("ephraim" C) -cmake_minimum_required(VERSION 2.6) +cmake_minimum_required(VERSION 2.8.1) +cmake_policy(VERSION 2.8.1) list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/erlang ${CMAKE_SOURCE_DIR}/cmake/vala) include(ErlangTarget) @@ -10,10 +11,11 @@ find_package(Erlang REQUIRED) find_package(Vala REQUIRED) ensure_vala_version("0.8" MINIMUM) - find_package(PkgConfig) pkg_check_modules(GTK REQUIRED gtk+-2.0) pkg_check_modules(GEE REQUIRED gee-1.0) -pkg_check_modules(ERL REQUIRED erl_interface) +pkg_check_modules(GIO REQUIRED gio-2.0) +pkg_check_modules(GIO_UNIX REQUIRED gio-unix-2.0) +pkg_check_modules(EVA REQUIRED eva) add_subdirectory(src) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 939f542..1f3f5df 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,12 @@ -add_definitions(${GTK_CFLAGS} ${GTK_CFLAGS_OTHER} ${GEE_CFLAGS} ${GEE_CFLAGS_OTHER} ${ERL_CFLAGS} ${ERL_CFLAGS_OTHER}) -link_libraries(${GTK_LIBRARIES} ${ERL_LIBRARIES} ${GEE_LIBRARIES}) -link_directories(${GTK_LIBRARY_DIRS} ${ERL_LIBRARY_DIRS} ${GEE_LIBRARY_DIRS}) +add_definitions( + ${GTK_CFLAGS} ${GTK_CFLAGS_OTHER} + ${GEE_CFLAGS} ${GEE_CFLAGS_OTHER} + ${GIO_CFLAGS} ${GIO_CFLAGS_OTHER} + ${GIO_UNIX_CFLAGS} ${GIO_UNIX_CFLAGS_OTHER} + ${EVA_CFLAGS} ${EVA_CFLAGS_OTHER} +) +link_libraries(${GTK_LIBRARIES} ${GEE_LIBRARIES} ${GIO_LIBRARIES} ${GIO_UNIX_LIBRARIES} ${EVA_LIBRARIES}) +link_directories(${GTK_LIBRARY_DIRS} ${GEE_LIBRARY_DIRS} ${GIO_LIBRARY_DIRS} ${GIO_UNIX_LIBRARY_DIRS} ${EVA_LIBRARY_DIRS}) add_subdirectory(core ${ephraim_BINARY_DIR}/core) add_subdirectory(gui ${ephraim_BINARY_DIR}/gui) diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index c49763c..9321f40 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -3,6 +3,7 @@ erl_target(ephraim-core ephraim_conn.erl ephraim_conv.erl ephraim_event.erl + ephraim_gui.erl ephraim_roster.erl ephraim_util.erl OPTIONS diff --git a/src/core/ephraim.erl b/src/core/ephraim.erl index c0ab7ae..b32e1d7 100644 --- a/src/core/ephraim.erl +++ b/src/core/ephraim.erl @@ -5,6 +5,7 @@ conn :: pid(), roster :: pid(), event :: pid(), + gui :: pid(), convs :: dict(), uis :: set() }). @@ -22,12 +23,12 @@ stop() -> -spec init() -> ok. init() -> register(ephraim, self()), - open_port({spawn_executable, "ephraim-gtk"}, [stream, use_stdio, out]), + GUI = spawn(ephraim_gui, init, []), Conn = spawn(ephraim_conn, init, []), Roster = spawn(ephraim_roster, init, []), Event = spawn(ephraim_event, init, []), - loop(#state{conn=Conn,roster=Roster,event=Event,convs=dict:new(),uis=sets:new()}), + loop(#state{conn=Conn,roster=Roster,event=Event,gui=GUI,convs=dict:new(),uis=sets:new()}), init:stop(). -spec get_conv(#state{},exmpp_jid:jid()) -> {#state{},pid()|undefined}. @@ -59,6 +60,7 @@ loop(State) -> State#state.conn ! stop, State#state.roster ! stop, State#state.event ! stop, + State#state.gui ! stop, ok; {register_ui, Pid} -> diff --git a/src/core/ephraim_gui.erl b/src/core/ephraim_gui.erl new file mode 100644 index 0000000..79433e0 --- /dev/null +++ b/src/core/ephraim_gui.erl @@ -0,0 +1,28 @@ +-module(ephraim_gui). +-compile([debug_info, export_all]). + +-spec init() -> ok. +init() -> + Port = open_port({spawn_executable, "ephraim-gtk"}, [binary, nouse_stdio, {packet, 4}]), + ephraim ! {register_ui, self()}, + loop(Port), + ephraim ! {unregister_ui, self()}. + +-spec loop(port()) -> ok. +loop(Port) -> + receive + stop -> + ok; + {Port, {data, Data}} -> + Msg = binary_to_term(Data), + case Msg of + stop -> + ok; + _ -> + ephraim ! Msg, + loop(Port) + end; + Msg -> + Port ! {self(), {command, term_to_binary(Msg)}}, + loop(Port) + end. diff --git a/src/ephraim b/src/ephraim index 5a6b8b8..ce30386 100755 --- a/src/ephraim +++ b/src/ephraim @@ -1,3 +1,3 @@ #!/bin/sh -erl -pa core -name ephraim-core@avalon.local -setcookie magiccookie -run ephraim +erl -pa core -run ephraim diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index dc65a0c..ac62f9a 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -12,7 +12,9 @@ vala_precompile(VALA_C PACKAGES gtk+-2.0 gee-1.0 - erl_interface + gio-2.0 + gio-unix-2.0 + eva OPTIONS --thread ) diff --git a/src/gui/CoreConnector.vala b/src/gui/CoreConnector.vala index d43ab2f..2e59701 100644 --- a/src/gui/CoreConnector.vala +++ b/src/gui/CoreConnector.vala @@ -1,35 +1,31 @@ public class CoreConnector { - unowned Thread thread; - bool running; + //unowned Thread thread; + //bool running; - Erl.Node node; - Erl.Connection con; - Erl.Term self; + //Erl.Node node; + //Erl.Connection con; + //Erl.Term self; + Eva.PacketHandler con; public signal void update_contact(Contact contact); public signal void new_conversation(string jid); public signal void receive_message(string jid, string type, string message); public signal void sent_message(string jid, string type, string message); - private class TermStore { + /*private class TermStore { public Erl.Term term; - } + }*/ - static construct { + /*static construct { Erl.init(); - } + }*/ public CoreConnector() { - running = false; + //running = false; } - public bool start() { - if(running) - return true; - - running = true; - - node = Erl.Node("ephraim-gtk", "magiccookie", 0); + public void start() { + /*node = Erl.Node("ephraim-gtk", "magiccookie", 0); con = node.connect("ephraim-core@avalon.local"); self = Erl.mk_self_pid(node); @@ -41,101 +37,77 @@ public class CoreConnector { return true; } catch(ThreadError e) { return false; - } + }*/ + + con = new Eva.PacketHandler(new UnixInputStream(3, true), new UnixOutputStream(4, true), 4); + con.received_term.connect(handle_term); + con.start(); } public void stop() { - if(!running) + /*if(!running) return; running = false; - thread.join(); - - con.reg_send("ephraim", Erl.format("{unregister_ui,~w}", self)); - } - - - private void* receive() { - while(running) { - TermStore response = new TermStore(); - Erl.ReceiveType ret = con.receive(out response.term, 1000); - - switch(ret) { - case Erl.ReceiveType.ERROR: - if(Erl.errno == Erl.Error.TIMEDOUT) - break; - - running = false; - break; - case Erl.ReceiveType.TICK: - // Do nothing - break; - case Erl.ReceiveType.MSG: - Idle.add(() => {handle_term(response); return false;}); - break; - } - } + receive.end();*/ - return null; + //con.reg_send("ephraim", Erl.format("{unregister_ui,~w}", self)); + con.send(new Eva.Atom("stop")); } - private Erl.Term? match(string pattern, Erl.Term term) { - Erl.Term pattern_term = Erl.format(pattern); - - if(pattern_term.match(term) != 0) - return pattern_term; - else - return null; + private static string from_utf8(Eva.Binary bin) { + string ret = ((string)bin.data).ndup(bin.len); + warn_if_fail(ret.validate()); + return ret; } - private void handle_term(TermStore store) { - unowned Erl.Term term = store.term; - Erl.Term match_term; + private void handle_term(Eva.Term term) { + Gee.Map<string, Eva.Term> match; - if((match_term = match("{roster_update,JID,Name,Subscription,Groups,Resources,Avatar}", term)) != null) { - Erl.Term jid_term = match_term.var_content("JID"); - if(!jid_term.is_binary()) + if((match = term.match(Eva.parse("{roster_update,JID,Name,Subscription,Groups,Resources,Avatar}"))) != null) { + Eva.Binary jid_term = match["JID"] as Eva.Binary; + if(jid_term == null) // TODO Debug output return; - string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); + string jid = from_utf8(jid_term); - Erl.Term name_term = match_term.var_content("Name"); + Eva.Binary name_term = match["Name"] as Eva.Binary; string? name; - if (name_term.is_binary()) - name = ((string)name_term.bin_ptr()).ndup(name_term.bin_size()); + if (name_term is Eva.Binary) + name = from_utf8(name_term); else name = null; Contact contact = new Contact(jid, name); - Erl.Term groups = match_term.var_content("Groups"); - while(groups.is_cons()) { - Erl.Term group_term = groups.hd(); + Eva.Cons groups = match["Groups"] as Eva.Cons; + while(groups != null) { + Eva.Binary group_term = groups.head as Eva.Binary; - if(group_term.is_binary()) { - string group = ((string)group_term.bin_ptr()).ndup(group_term.bin_size()); + if(group_term != null) { + string group = Eva.binary_to_string(group_term.data, group_term.len); contact.add_group(group); } - groups = groups.tl(); + groups = groups.tail as Eva.Cons; } - Erl.Term resources = match_term.var_content("Resources"); - while(resources.is_cons()) { - Erl.Term r; + Eva.Cons resources = match["Resources"] as Eva.Cons; + while(resources != null) { + Gee.Map<string, Eva.Term> r; - if((r = match("{Name,{resource_entry,Priority,Show,Status}}", resources.hd())) != null) { - Erl.Term rname_term = r.var_content("Name"); - Erl.Term prio_term = r.var_content("Priority"); - Erl.Term show_term = r.var_content("Show"); - Erl.Term status_term = r.var_content("Status"); + if((r = resources.head.match(Eva.parse("{Name,{resource_entry,Priority,Show,Status}}"))) != null) { + Eva.Binary rname_term = r["Name"] as Eva.Binary; + Eva.Numeric prio_term = r["Priority"] as Eva.Numeric; + Eva.Atom show_term = r["Show"] as Eva.Atom; + Eva.Binary status_term = r["Status"] as Eva.Binary; - if(rname_term.is_binary() && prio_term.is_integer() && show_term.is_atom()) { - string rname = ((string)rname_term.bin_ptr()).ndup(rname_term.bin_size()); - int prio = prio_term.int_value(); + if(rname_term != null && prio_term != null && show_term != null) { + string rname = from_utf8(rname_term); + int prio = prio_term.int_value; Contact.Show show = Contact.Show.UNDEFINED; - switch((string)show_term.atom_ptr()) { + switch(show_term.value) { case "online": show = Contact.Show.ONLINE; break; @@ -154,22 +126,22 @@ public class CoreConnector { } string? status = null; - if(status_term.is_binary()) - status = ((string)status_term.bin_ptr()).ndup(status_term.bin_size()); + if(status_term != null) + status = from_utf8(status_term); contact.update_resource(rname, new Contact.Resource(prio, show, status)); } } - resources = resources.tl(); + resources = resources.tail as Eva.Cons; } - Erl.Term avatar = match("{avatar,Data}", match_term.var_content("Avatar")); + Gee.Map<string, Eva.Term> avatar = match["Avatar"].match(Eva.parse("{avatar,Data}")); if(avatar != null) { - Erl.Term avatarData = avatar.var_content("Data"); + Eva.Binary avatarData = avatar["Data"] as Eva.Binary; - if(avatarData.is_binary()) { - InputStream avatarStream = new MemoryInputStream.from_data(avatarData.bin_ptr(), avatarData.bin_size(), null); + if(avatarData != null) { + InputStream avatarStream = new MemoryInputStream.from_data(avatarData.data, avatarData.len, null); try { contact.avatar = new Gdk.Pixbuf.from_stream_at_scale(avatarStream, 32, 32, true, null); avatarStream.close(null); @@ -178,71 +150,72 @@ public class CoreConnector { } } } - update_contact(contact); } - else if((match_term = match("{new_conversation,JID}", term)) != null) { - Erl.Term jid_term = match_term.var_content("JID"); - if(!jid_term.is_binary()) + else if((match = term.match(Eva.parse("{new_conversation,JID}"))) != null) { + Eva.Binary jid_term = match["JID"] as Eva.Binary; + if(jid_term == null) // TODO Debug output return; - string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); + string jid = from_utf8(jid_term); new_conversation(jid); } - else if((match_term = match("{receive_message,JID,Type,Body}", term)) != null) { - Erl.Term jid_term = match_term.var_content("JID"); - if(!jid_term.is_binary()) + else if((match = term.match(Eva.parse("{receive_message,JID,Type,Body}"))) != null) { + Eva.Binary jid_term = match["JID"] as Eva.Binary; + if(jid_term == null) // TODO Debug output return; - string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); + string jid = from_utf8(jid_term); - Erl.Term type_term = match_term.var_content("Type"); - if(!type_term.is_atom()) + Eva.Atom type_term = match["Type"] as Eva.Atom; + if(type_term == null) // TODO Debug output return; - string type = ((string)type_term.atom_ptr()).ndup(type_term.atom_size()); + string type = type_term.value; - Erl.Term body_term = match_term.var_content("Body"); - if(!body_term.is_binary()) + Eva.Binary body_term = match["Body"] as Eva.Binary; + if(body_term == null) // TODO Debug output return; - string body = ((string)body_term.bin_ptr()).ndup(body_term.bin_size()); + string body = from_utf8(body_term); receive_message(jid, type, body); } - else if((match_term = match("{sent_message,JID,Type,Body}", term)) != null) { - Erl.Term jid_term = match_term.var_content("JID"); - if(!jid_term.is_binary()) + else if((match = term.match(Eva.parse("{sent_message,JID,Type,Body}"))) != null) { + Eva.Binary jid_term = match["JID"] as Eva.Binary; + if(jid_term == null) // TODO Debug output return; - string jid = ((string)jid_term.bin_ptr()).ndup(jid_term.bin_size()); + string jid = from_utf8(jid_term); - Erl.Term type_term = match_term.var_content("Type"); - if(!type_term.is_atom()) + Eva.Atom type_term = match["Type"] as Eva.Atom; + if(type_term == null) // TODO Debug output return; - string type = ((string)type_term.atom_ptr()).ndup(type_term.atom_size()); + string type = type_term.value; - Erl.Term body_term = match_term.var_content("Body"); - if(!body_term.is_binary()) + Eva.Binary body_term = match["Body"] as Eva.Binary; + if(body_term == null) // TODO Debug output return; - string body = ((string)body_term.bin_ptr()).ndup(body_term.bin_size()); + string body = from_utf8(body_term); sent_message(jid, type, body); } else { - Erl.print_term(stdout, term); - stdout.printf("\n"); + stdout.printf("%s\n", term.to_string()); } } - + public void start_conversation(string jid) { - con.reg_send("ephraim", Erl.format("{start_conversation,~w}", Erl.mk_binary(jid.to_utf8()))); + char[] jid_utf8 = jid.to_utf8(); + con.send(Eva.parse("{start_conversation,~w}", new Eva.Binary(jid_utf8))); } public void send_message(string jid, string type, string message) { - con.reg_send("ephraim", Erl.format("{send_message,~w,~a,~w}", Erl.mk_binary(jid.to_utf8()), type, Erl.mk_binary(message.to_utf8()))); + char[] jid_utf8 = jid.to_utf8(); + char[] message_utf8 = message.to_utf8(); + con.send(Eva.parse("{send_message,~w,~a,~w}", new Eva.Binary(jid_utf8), type, new Eva.Binary(message_utf8))); } } diff --git a/src/gui/Ephraim.vala b/src/gui/Ephraim.vala index 99a7a48..50f83e1 100644 --- a/src/gui/Ephraim.vala +++ b/src/gui/Ephraim.vala @@ -57,8 +57,9 @@ public class Ephraim { conversations[jid].sent_message(type, message); }); - if(!coreconn.start()) - return 1; + //if(!coreconn.start()) + // return 1; + coreconn.start(); window.visible = true; |