static void infinoted_plugin_document_stream_subscribe_done( InfinotedPluginDocumentStreamStream* stream, InfSessionProxy* proxy) { InfSession* session; GParameter params[2] = { { "name", { 0 } }, { "status", { 0 } } }; g_assert(stream->proxy == NULL); stream->proxy = proxy; g_object_ref(proxy); g_object_get(G_OBJECT(proxy), "session", &session, NULL); /* User join via document stream only works for chat sessions * at the moment. */ if(stream->username == NULL || *stream->username == '\0' || INF_TEXT_IS_SESSION(session)) { infinoted_plugin_document_stream_start(stream); } else if(INF_IS_CHAT_SESSION(session)) { g_value_init(¶ms[0].value, G_TYPE_STRING); g_value_set_static_string(¶ms[0].value, stream->username); g_value_init(¶ms[1].value, INF_TYPE_USER_STATUS); g_value_set_enum(¶ms[1].value, INF_USER_ACTIVE); /* Join a user */ stream->user_request = inf_session_proxy_join_user( INF_SESSION_PROXY(proxy), 2, params, infinoted_plugin_document_stream_user_join_func, stream ); } else { g_assert_not_reached(); } g_object_unref(session); }
static void infinoted_plugin_document_stream_start( InfinotedPluginDocumentStreamStream* stream) { InfSession* session; InfBuffer* buffer; g_object_get(G_OBJECT(stream->proxy), "session", &session, NULL); buffer = inf_session_get_buffer(session); stream->buffer = buffer; g_object_ref(buffer); if(INF_TEXT_IS_SESSION(session)) { infinoted_plugin_document_stream_sync_text(stream); g_signal_connect( G_OBJECT(buffer), "text-inserted", G_CALLBACK(infinoted_plugin_document_stream_text_inserted_cb), stream ); g_signal_connect( G_OBJECT(buffer), "text-erased", G_CALLBACK(infinoted_plugin_document_stream_text_erased_cb), stream ); } else if(INF_IS_CHAT_SESSION(session)) { infinoted_plugin_document_stream_sync_chat(stream); g_signal_connect_after( G_OBJECT(buffer), "add-message", G_CALLBACK(infinoted_plugin_document_stream_chat_add_message_cb), stream ); } g_object_unref(session); }
static void infinoted_directory_sync_directory_remove_session_cb(InfdDirectory* directory, InfdDirectoryIter* iter, InfdSessionProxy* proxy, gpointer user_data) { InfinotedDirectorySync* dsync; InfinotedDirectorySyncSession* session; /* Ignore if this is not a text session */ if(INF_TEXT_IS_SESSION(infd_session_proxy_get_session(proxy))) { dsync = (InfinotedDirectorySync*)user_data; session = infinoted_directory_sync_find_session(dsync, iter); g_assert(session != NULL && session->proxy == proxy); infinoted_directory_sync_remove_session(dsync, session); } }
static gboolean infinoted_directory_sync_add_session(InfinotedDirectorySync* dsync, InfdDirectoryIter* iter, GError** error) { InfinotedDirectorySyncSession* session; InfdSessionProxy* proxy; InfBuffer* buffer; gchar* iter_path; #ifdef G_OS_WIN32 gchar* pos; #endif gchar* full_path; gchar* converted; g_assert(infinoted_directory_sync_find_session(dsync, iter) == NULL); proxy = infd_directory_iter_peek_session(dsync->directory, iter); g_assert(proxy != NULL); /* Ignore if this is not a text session */ if(!INF_TEXT_IS_SESSION(infd_session_proxy_get_session(proxy))) return TRUE; iter_path = infd_directory_iter_get_path(dsync->directory, iter); #ifdef G_OS_WIN32 for(pos = iter_path; *pos != '\0'; ++pos) { if(*pos == '\\') { g_set_error( error, infinoted_directory_sync_error_quark(), INFINOTED_DIRECTORY_SYNC_ERROR_INVALID_PATH, _("Node \"%s\" contains invalid characters"), iter_path ); g_free(iter_path); return FALSE; } else if(*pos == '/') { *pos = '\\'; } } #endif full_path = g_build_filename(dsync->sync_directory, iter_path+1, NULL); g_free(iter_path); converted = g_filename_from_utf8(full_path, -1, NULL, NULL, error); g_free(full_path); if(!converted) return FALSE; session = g_slice_new(InfinotedDirectorySyncSession); session->dsync = dsync; session->iter = *iter; session->proxy = proxy; session->timeout = NULL; session->path = converted; dsync->sessions = g_slist_prepend(dsync->sessions, session); buffer = inf_session_get_buffer(infd_session_proxy_get_session(proxy)); g_signal_connect( G_OBJECT(buffer), "text-inserted", G_CALLBACK(infinoted_directory_sync_buffer_text_inserted_cb), session ); g_signal_connect( G_OBJECT(buffer), "text-erased", G_CALLBACK(infinoted_directory_sync_buffer_text_erased_cb), session ); infinoted_directory_sync_session_save(dsync, session); return TRUE; }
static gboolean infd_note_plugin_text_session_write(InfdStorage* storage, InfSession* session, const gchar* path, gpointer user_data, GError** error) { InfUserTable* table; InfTextBuffer* buffer; InfTextBufferIter* iter; xmlNodePtr root; xmlNodePtr buffer_node; xmlNodePtr segment_node; guint author; gchar* content; gsize bytes; FILE* stream; xmlDocPtr doc; xmlErrorPtr xmlerror; g_assert(INFD_IS_FILESYSTEM_STORAGE(storage)); g_assert(INF_TEXT_IS_SESSION(session)); /* Open stream before exporting buffer to XML so possible errors are * catched earlier. */ stream = infd_filesystem_storage_open( INFD_FILESYSTEM_STORAGE(storage), "InfText", path, "w", error ); if(stream == NULL) return FALSE; root = xmlNewNode(NULL, (const xmlChar*)"inf-text-session"); buffer = INF_TEXT_BUFFER(inf_session_get_buffer(session)); table = inf_session_get_user_table(session); inf_user_table_foreach_user( table, infd_note_plugin_text_session_write_foreach_user_func, root ); buffer_node = xmlNewChild(root, NULL, (const xmlChar*)"buffer", NULL); iter = inf_text_buffer_create_iter(buffer); if(iter != NULL) { do { author = inf_text_buffer_iter_get_author(buffer, iter); content = inf_text_buffer_iter_get_text(buffer, iter); bytes = inf_text_buffer_iter_get_bytes(buffer, iter); segment_node = xmlNewChild( buffer_node, NULL, (const xmlChar*)"segment", NULL ); inf_xml_util_set_attribute_uint(segment_node, "author", author); inf_xml_util_add_child_text(segment_node, content, bytes); g_free(content); } while(inf_text_buffer_iter_next(buffer, iter)); inf_text_buffer_destroy_iter(buffer, iter); } doc = xmlNewDoc((const xmlChar*)"1.0"); xmlDocSetRootElement(doc, root); if(xmlDocFormatDump(stream, doc, 1) == -1) { xmlerror = xmlGetLastError(); fclose(stream); xmlFreeDoc(doc); g_set_error( error, g_quark_from_static_string("LIBXML2_OUTPUT_ERROR"), xmlerror->code, "%s", xmlerror->message ); return FALSE; } fclose(stream); xmlFreeDoc(doc); return TRUE; }