77 Commits

Author SHA1 Message Date
8d95dd913c WIP: Refactor GIR creation 2018-03-12 07:59:54 +01:00
4f630186d7 WIP: Add API methods for listing and fetching devices 2018-03-12 07:59:54 +01:00
429b1711cd Add API method for /notifications 2018-03-12 07:59:54 +01:00
d3c6760d27 Add API method for /joined_rooms 2018-03-12 07:59:54 +01:00
723d7c5485 Add API method for email based account registration 2018-03-12 07:59:54 +01:00
cec83e7bae Add API method for /account/whoami 2018-03-12 07:59:54 +01:00
d310f34228 Add MATRIX_RECEIPT_TYPE_UNKNOWN 2018-03-12 07:59:54 +01:00
4132035bcd Create setter for MatrixAPI.user_id and MatrixAPI.homeserver 2018-03-12 07:59:54 +01:00
c8bc5e7d6b Remove the refresh_token
It was removed from the spec, and from HS implementations for a while.
2018-03-12 07:59:54 +01:00
3149fff095 Don’t download avatar if it is NULL in test-api-client 2018-03-12 07:59:54 +01:00
5242549a68 WIP: Completely remove Vala as a dependency 2018-03-12 07:59:54 +01:00
08f3dc66cd LOCAL ONLY! Add Makefile rule to generate a .dir-locals.el file 2018-03-12 07:59:54 +01:00
b8a98209dd Hide deprecation warnings during library compilation
We now define `__MATRIX_GLIB_SDK_COMPILATION` in `src/Makefile.am`, which in turn disables
deprecation of symbols.
2018-03-12 07:59:54 +01:00
cfa4ec43d9 Make use of configure --enable-maintainer-mode
Currently it adds `-O0` to `CFLAGS`.
2018-03-12 07:59:54 +01:00
55fcb3cbf7 Move from valadoc generation to GTK-Doc 2018-03-12 07:59:54 +01:00
8aad092c6f Port MatrixHTTPClient to C 2018-03-12 07:59:54 +01:00
0f848dec5e Port MatrixClient to C 2018-03-12 07:59:53 +01:00
b03bddd20d Port MatrixHTTPAPI to C 2018-03-12 07:59:53 +01:00
623de1e432 Port MatrixAPI to C 2018-03-12 07:59:53 +01:00
664f3a0ff6 Port MatrixEventCallCandidates to C 2018-03-12 07:59:53 +01:00
d51ab6ec50 Port MatrixEventRoomThirdPartyInvite to C 2018-03-12 07:59:53 +01:00
fffc0a615b Port MatrixEventRoomRedaction to C 2018-03-12 07:59:53 +01:00
2a083ab105 Port MatrixEventRoomGuestAccess to C 2018-03-12 07:59:53 +01:00
25cb2e33d9 Port MatrixEventRoomMessageFeedback to C 2018-03-12 07:59:53 +01:00
e461e05250 Port MatrixEventRoomPowerLevels to C 2018-03-12 07:59:53 +01:00
284e1b7390 Port MatrixEventRoomCreate to C 2018-03-12 07:59:53 +01:00
42ae6bd943 Port MatrixEventRoomCanonicalAlias to C 2018-03-12 07:59:53 +01:00
c5ccfe7a8b Port MatrixEventCallInvite to C 2018-03-12 07:59:53 +01:00
89fe509792 Port MatrixEventCallHangup to C 2018-03-12 07:59:53 +01:00
fc4a0a8433 Port MatrixEventCallAnswer to C 2018-03-12 07:59:53 +01:00
ed579294d2 Port MatrixEventRoomJoinRules to C 2018-03-12 07:59:53 +01:00
b0b1d5d26d Port MatrixEventRoomHistoryVisibility to C 2018-03-12 07:59:53 +01:00
7299d04285 Add parameter descriptions to test-client’s parameters 2018-03-12 07:59:53 +01:00
5f004a3965 Port MatrixEventRoomMessage to C 2018-03-12 07:59:53 +01:00
358fa883ef Port MatrixMessageNotice to C 2018-03-12 07:59:53 +01:00
aede0eeef9 Port MatrixRoom to C 2018-03-12 07:59:53 +01:00
0a2d65b0fd Port MatrixMessageVideo to C 2018-02-28 15:09:05 +01:00
d2ec7e9507 Port MatrixMessageAudio to C 2018-02-28 15:09:05 +01:00
a599541184 Port MatrixMessageImage to C 2018-02-28 15:09:05 +01:00
a9cddf4303 Port MatrixMessageFile to C 2018-02-28 15:09:05 +01:00
3c825c663f Port MatrixEventCall to C 2018-02-28 15:09:05 +01:00
d43f6517d7 Port MatrixEventRoomName to C 2018-02-28 15:09:05 +01:00
350afd8ca1 Port MatrixEventRoomAvatar to C 2018-02-28 15:09:05 +01:00
a6899e054f Port MatrixMessageEmote to C 2018-02-28 15:09:05 +01:00
3b61d2997e Port MatrixMessageLocation to C 2018-02-28 15:09:05 +01:00
49a2bf4aa9 Port MatrixMessageText to C 2018-02-28 15:09:05 +01:00
81521688e8 Port MatrixMessageBase to C 2018-02-28 15:09:04 +01:00
10a27bef17 Port MatrixEventRoomAliases to C 2018-02-28 15:09:04 +01:00
171f76e678 Port MatrixEventRoomTopic to C 2018-02-28 15:09:04 +01:00
75c255ac9d Port MatrixEventReceipt to C 2018-02-28 15:09:04 +01:00
068f85d0c1 Port MatrixEventTyping to C 2018-02-28 15:09:04 +01:00
e23a177851 Port MatrixEventRoomMember to C 2018-02-28 15:09:04 +01:00
68058c60ff Port MatrixEventPresence to C 2018-02-28 15:09:04 +01:00
3dcaf44540 Port MatrixEventTag to C 2018-02-28 15:09:04 +01:00
149c9fec36 Port MatrixEventState to C 2018-02-28 15:09:04 +01:00
64d1674816 Port MatrixEventRoom to C 2018-02-28 15:09:04 +01:00
552a36d65d Port MatrixEventBase to C 2018-02-28 15:09:04 +01:00
89376c0890 Port _matrix_json_node_deep_copy() to C 2018-02-28 15:09:04 +01:00
532bb0d153 Port MatrixSearchCategories to C 2018-02-28 15:09:04 +01:00
fce95296eb Port MatrixSearchRoomEvents to C 2018-02-28 15:09:04 +01:00
cb170dc4d9 Upgrade _matrix_g_enum_to_string() so it can convert dashes to any character 2018-02-28 15:09:04 +01:00
91fb94de91 Port MatrixSearchGroupings to C 2018-02-28 15:09:04 +01:00
7644e8f2e0 Upgrade free_str_array() so it can free any type of arrays 2018-02-28 15:09:04 +01:00
0917378fea Port MatrixSearchGrouping to C 2018-02-28 15:09:04 +01:00
de33224f55 Port MatrixEventContext to C 2018-02-28 15:09:04 +01:00
d3db60e50d Port MatrixPusher to C 2018-02-28 15:09:04 +01:00
f5df3831a3 Port Matrix3PidCredential to C 2018-02-28 15:09:03 +01:00
eff98aad31 Port MatrixFilter to C 2018-02-28 08:01:22 +01:00
161b60a2b0 Port MatrixRoomFilter to C 2018-02-28 08:01:22 +01:00
5108a2a825 Port MatrixFilterRules to C 2018-02-28 08:01:22 +01:00
57a519b8db Port MatrixJsonCompact to C 2018-02-28 08:01:22 +01:00
41295e4b33 Port MatrixProfile to C 2018-02-28 08:01:22 +01:00
bd06d8d14a Port MatrixVideoInfo to C 2018-02-28 08:01:22 +01:00
1edee561ae Port MatrixAudioInfo to C 2018-02-28 08:01:07 +01:00
817dc4800e Port MatrixImageInfo to C 2018-02-28 08:01:07 +01:00
668bedb816 Port MatrixFileInfo to C 2017-12-12 11:50:09 +01:00
f6f6f78cdc Port _g_enum_nick_to_value() to C 2017-12-12 11:50:09 +01:00
152 changed files with 32935 additions and 10429 deletions

46
.gitignore vendored
View File

@@ -36,61 +36,17 @@ Makefile.in
/GTAGS /GTAGS
/INSTALL /INSTALL
/ChangeLog /ChangeLog
/.dir-locals.el
/src/matrix-version.h /src/matrix-version.h
/src/matrix-enumtypes.[ch] /src/matrix-enumtypes.[ch]
/src/matrix-marshalers.[ch] /src/matrix-marshalers.[ch]
/src/stamp-matrix-marshalers /src/stamp-matrix-marshalers
/docs/valadoc/gtk-doc/gtk-doc
# Vala related files # Vala related files
/src/Matrix-0.0.vapi /src/Matrix-0.0.vapi
/src/vala-temp /src/vala-temp
/src/vala-stamp /src/vala-stamp
/src/matrix-glib.h /src/matrix-glib.h
/src/matrix-api.c
/src/matrix-client.c
/src/matrix-types.c
/src/matrix-http-api.c
/src/matrix-http-client.c
/src/matrix-compacts.c
/src/matrix-event-base.c
/src/matrix-event-presence.c
/src/matrix-event-room-base.c
/src/matrix-event-room-member.c
/src/matrix-event-state-base.c
/src/matrix-event-room-message.c
/src/namespace-info.vala /src/namespace-info.vala
/src/namespace-info.c /src/namespace-info.c
/src/matrix-event-room-topic.c
/src/matrix-event-typing.c
/src/matrix-event-room-aliases.c
/src/matrix-event-receipt.c
/src/matrix-event-room-history-visibility.c
/src/matrix-event-room-join-rules.c
/src/matrix-event-room-name.c
/src/matrix-event-tag.c
/src/matrix-event-room-canonical-alias.c
/src/matrix-event-room-create.c
/src/matrix-event-room-power-levels.c
/src/matrix-event-room-avatar.c
/src/matrix-event-room-message-feedback.c
/src/matrix-event-room-guest-access.c
/src/matrix-event-room-redaction.c
/src/matrix-event-room-third-party-invite.c
/src/matrix-event-call-invite.c
/src/matrix-event-call-candidates.c
/src/matrix-event-call-answer.c
/src/matrix-event-call-hangup.c
/src/matrix-event-call-base.c
/src/matrix-glib-0.0.pc /src/matrix-glib-0.0.pc
/src/matrix-message-base.c
/src/matrix-message-text.c
/src/matrix-message-emote.c
/src/matrix-message-notice.c
/src/matrix-message-file.c
/src/matrix-message-image.c
/src/matrix-message-audio.c
/src/matrix-message-video.c
/src/matrix-message-location.c
/src/matrix-profile.c
/src/matrix-room.c

View File

@@ -3,8 +3,8 @@ ACLOCAL_AMFLAGS = -I m4 ${ACLOCAL_FLAGS}
# Set up subdirectories to traverse # Set up subdirectories to traverse
SUBDIRS = src SUBDIRS = src
if ENABLE_DOCS if ENABLE_GTK_DOC
SUBDIRS += docs SUBDIRS += docs/reference/matrix-glib-sdk
endif endif
# Specify files to include in dist # Specify files to include in dist
@@ -63,4 +63,22 @@ ChangeLog:
echo A git checkout and git-log is required to generate this file >> $@); \ echo A git checkout and git-log is required to generate this file >> $@); \
fi fi
.PHONY: ChangeLog .PHONY: ChangeLog .dir-locals.el
.dir-locals.el:
@echo -n ""; \
includes=`echo -I$(top_srcdir) $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(SOUP_CFLAGS) $(JSON_CFLAGS) $(VALA_CFLAGS) | tr " " "\n" | grep '^-I' | sed 's/^-I//'`; \
flycheck_path='('; \
company_path='('; \
for incl in $$includes; \
do \
if [ "$$incl" == "." ]; \
then \
incl="$(abs_top_srcdir)"; \
fi; \
flycheck_path="$$flycheck_path \"$$incl\""; \
company_path="$$company_path \"-I$$incl\""; \
done; \
flycheck_path="$$flycheck_path)"; \
company_path="$$company_path)"; \
echo "((c-mode . ((flycheck-clang-include-path . $$flycheck_path) (company-clang-arguments . $$company_path))))" > $@

View File

@@ -29,7 +29,6 @@ For a working example, see [test-client.c](src/test-client.c).
// Set tokens for the session. Alternatively you may want to login with matrix_api_login() or matrix_client_login_with_password() // Set tokens for the session. Alternatively you may want to login with matrix_api_login() or matrix_client_login_with_password()
matrix_api_set_token(MATRIX_API(client), "your_access_token"); matrix_api_set_token(MATRIX_API(client), "your_access_token");
matrix_api_set_refresh_token(MATRIX_API(client), "your_refresh_token");
// Connect a callback that gets called when a m.room.message event arrives // Connect a callback that gets called when a m.room.message event arrives
matrix_client_connect_event(client, MATRIX_EVENT_TYPE_ROOM_MESSAGE, message_callback, NULL); matrix_client_connect_event(client, MATRIX_EVENT_TYPE_ROOM_MESSAGE, message_callback, NULL);

View File

@@ -8,13 +8,22 @@ DIE=0
PKG_NAME="matrix-glib" PKG_NAME="matrix-glib"
(test -f "$srcdir/configure.ac" \ (test -f "$srcdir/configure.ac" \
&& test -f "$srcdir/src/matrix-client.vala") || { && test -f "$srcdir/src/matrix-client.c") || {
echo -n "**Error**: Directory "\`$srcdir\'" does not look like the" echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
echo " top-level $PKG_NAME directory" echo " top-level $PKG_NAME directory"
exit 1 exit 1
} }
(gtkdocize --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`gtkdocize' installed."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnome.org/"
DIE=1
}
(autoconf --version) < /dev/null > /dev/null 2>&1 || { (autoconf --version) < /dev/null > /dev/null 2>&1 || {
echo echo
echo "**Error**: You must have \`autoconf' installed." echo "**Error**: You must have \`autoconf' installed."
@@ -96,6 +105,11 @@ fi
echo "Running aclocal $aclocalinclude ..." echo "Running aclocal $aclocalinclude ..."
aclocal $m4dir $ACLOCAL_FLAGS $aclocalinclude || exit $? aclocal $m4dir $ACLOCAL_FLAGS $aclocalinclude || exit $?
if grep "^GTK_DOC_CHECK" "$coin" > /dev/null; then
echo "Running gtkdocize ..."
gtkdocize || exit $?
fi
if grep "^A[CM]_CONFIG_HEADER" "$coin" > /dev/null; then if grep "^A[CM]_CONFIG_HEADER" "$coin" > /dev/null; then
echo "Running autoheader ..." echo "Running autoheader ..."
autoheader || exit $? autoheader || exit $?

View File

@@ -93,15 +93,17 @@ LIBVALA_REQUIRED=0.30
GIO_REQUIRED=2.22 GIO_REQUIRED=2.22
SOUP_REQUIRED=2.44.2 SOUP_REQUIRED=2.44.2
JSON_REQUIRED=0.16.2 JSON_REQUIRED=0.16.2
VALADOC_REQUIRED=0.3.1
# Check GLib # Check GLib
PKG_CHECK_MODULES([GLIB], PKG_CHECK_MODULES([GLIB],
[glib-2.0 >= $GLIB_REQUIRED [glib-2.0 >= $GLIB_REQUIRED
gobject-2.0 >= $GLIB_REQUIRED]) gobject-2.0 >= $GLIB_REQUIRED])
# Check for vala m4_ifdef([GTK_DOC_CHECK], [
VALAC_CHECK GTK_DOC_CHECK([1.25], [--flavour no-tmpl])
], [
AM_CONDITIONAL([ENABLE_GTK_DOC], false)
])
# Check for GIO # Check for GIO
PKG_CHECK_MODULES([GIO], [gio-2.0 >= $GIO_REQUIRED]) PKG_CHECK_MODULES([GIO], [gio-2.0 >= $GIO_REQUIRED])
@@ -113,53 +115,20 @@ PKG_CHECK_MODULES([SOUP], [libsoup-2.4 >= $SOUP_REQUIRED])
PKG_CHECK_MODULES([JSON], [json-glib-1.0 >= $JSON_REQUIRED]) PKG_CHECK_MODULES([JSON], [json-glib-1.0 >= $JSON_REQUIRED])
# Check for GObject Introspection # Check for GObject Introspection
m4_ifdef([GOBJECT_INTROSPECTION_CHECK], [
GOBJECT_INTROSPECTION_CHECK([1.32.0]) GOBJECT_INTROSPECTION_CHECK([1.32.0])
],[
AM_CONDITIONAL([HAVE_INTROSPECTION], false)
])
# Documentation with Valadoc m4_ifdef([VALA_PROG_VAPIGEN], [
AC_ARG_ENABLE([docs], VALAC_CHECK([0.38], [0.38])
AS_HELP_STRING([--enable-docs],
[Enable documentation generation]),
[enable_docs=$enableval], [enable_docs=no])
AM_CONDITIONAL([ENABLE_DOCS], [test x$enable_docs = xyes])
have_valadoc=no VALA_PROG_VAPIGEN([0.38])
if test x$enable_docs = xyes; then AM_CONDITIONAL([HAVE_VAPIGEN], true)
# Make sure the library is new enough and the program exists ],[
AC_PATH_PROG([VALADOC], [valadoc], [no]) AM_CONDITIONAL([HAVE_VAPIGEN], false)
if test "x$VALADOC" = "xno"; then ])
AC_MSG_RESULT([valadoc documentation will not build because valadoc is not found])
else
VAPIDIR=`$PKG_CONFIG --variable=vapidir libvala-$LIBVALA_REQUIRED`
have_valadoc="yes"
AC_SUBST([VALADOC])
fi
fi
AM_CONDITIONAL([HAVE_VALADOC], [test x$have_valadoc = xyes])
AC_ARG_ENABLE([gtk-doc],
AS_HELP_STRING([--enable-gtk-doc],
[Enable GTK-Doc documentation generation]),
[enable_gtk_docs=$enableval], [enable_gtk_docs=no])
have_gtkdoc=no
if test x$enable_gtk_docs = xyes; then
if test x$have_valadoc = xyes; then
PKG_CHECK_MODULES([GTKDOC], gtk-doc)
have_gtkdoc=yes
else
AC_MSG_ERROR([valadoc is required to generate GTK-Doc documentation. Use --enable-valadoc])
fi
fi
gtkdocs=no
if test x$enable_docs = xyes; then
if test x$enable_gtk_docs = xyes; then
gtkdocs=yes
fi
fi
AM_CONDITIONAL([ENABLE_GTK_DOCS], [test "x$gtkdocs" = "xyes"])
debug=no debug=no
AC_ARG_ENABLE(debug, AC_ARG_ENABLE(debug,
@@ -174,7 +143,14 @@ if test x"$debug" = x"$enableval"; then
if test x"$cflags_set" != x"set"; then if test x"$cflags_set" != x"set"; then
case " $CFLAGS " in case " $CFLAGS " in
*[[\ \ ]]-g[[\ \ ]]*) ;; *[[\ \ ]]-g[[\ \ ]]*) ;;
*) CFLAGS="$CFLAGS -g" ;; *)
CFLAGS="$CFLAGS -g"
if test x"$USE_MAINTAINER_MODE" = x"$enableval"; then
CFLAGS="$CFLAGS -O0"
fi
;;
esac esac
fi fi
else else
@@ -201,10 +177,7 @@ AC_CONFIG_FILES([
src/Makefile src/Makefile
src/matrix-version.h src/matrix-version.h
src/matrix-glib-0.0.pc src/matrix-glib-0.0.pc
src/namespace-info.vala docs/reference/matrix-glib-sdk/Makefile
docs/Makefile
docs/valadoc/Makefile
docs/valadoc/gtk-doc/Makefile
]) ])
AC_OUTPUT AC_OUTPUT
@@ -212,7 +185,6 @@ AC_OUTPUT
echo "" echo ""
echo " Configuration summary for Matrix-$MATRIX_GLIB_VERSION" echo " Configuration summary for Matrix-$MATRIX_GLIB_VERSION"
echo " Installation prefix: $prefix" echo " Installation prefix: $prefix"
echo " Documentation: ${enable_docs}" echo " Documentation: ${enable_gtk_doc}"
echo " Gtk-Doc: `if test x${gtkdocs} = xyes; then echo yes; else echo no; fi`"
echo " Debug: $debug" echo " Debug: $debug"
echo "" echo ""

View File

@@ -1,5 +1 @@
SUBDIRS = SUBDIRS =
if HAVE_VALADOC
SUBDIRS += valadoc
endif

View File

@@ -0,0 +1,85 @@
# This is a blank Makefile.am for using gtk-doc.
# Copy this to your project's API docs directory and modify the variables to
# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples
# of using the various options.
# The name of the module, e.g. 'glib'.
DOC_MODULE=matrix-glib-sdk
# Uncomment for versioned docs and specify the version of the module, e.g. '2'.
#DOC_MODULE_VERSION=2
# The top-level XML file.
DOC_MAIN_SGML_FILE=$(DOC_MODULE)-docs.xml
# Directories containing the source code.
# gtk-doc will search all .c and .h files beneath these paths
# for inline comments documenting functions and macros.
# e.g. DOC_SOURCE_DIR=$(top_srcdir)/gtk $(top_srcdir)/gdk
DOC_SOURCE_DIR=$(top_srcdir)/src
# Extra options to pass to gtkdoc-scangobj. Normally not needed.
SCANGOBJ_OPTIONS=
# Extra options to supply to gtkdoc-scan.
# e.g. SCAN_OPTIONS=--deprecated-guards="GTK_DISABLE_DEPRECATED"
SCAN_OPTIONS=
# Extra options to supply to gtkdoc-mkdb
# e.g. MKDB_OPTIONS=--xml-mode --output-format=xml
MKDB_OPTIONS=--xml-mode --output-format=xml
# Extra options to supply to gtkdoc-mkhtml
MKHTML_OPTIONS=
# Extra options to supply to gtkdoc-fixref. Normally not needed.
# e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html
FIXXREF_OPTIONS=
# Used for dependencies. The docs will be rebuilt if any of these change.
# e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h
# e.g. CFILE_GLOB=$(top_srcdir)/gtk/*.c
HFILE_GLOB=$(top_srcdir)/src/*.h
CFILE_GLOB=$(top_srcdir)/src/*.c
# Extra header to include when scanning, which are not under DOC_SOURCE_DIR
# e.g. EXTRA_HFILES=$(top_srcdir}/contrib/extra.h
EXTRA_HFILES=
# Header files or dirs to ignore when scanning. Use base file/dir names
# e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h private_code
IGNORE_HFILES=utils.h
# Images to copy into HTML directory.
# e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
HTML_IMAGES=
# Extra files that are included by $(DOC_MAIN_SGML_FILE).
# e.g. content_files=running.xml building.xml changes-2.0.xml
content_files=
# Files where gtk-doc abbrevations (#GtkWidget) are expanded
# e.g. expand_content_files=running.xml
expand_content_files=
# CFLAGS and LDFLAGS for compiling gtkdoc-scangobj with your library.
# Only needed if you are using gtkdoc-scangobj to dynamically query widget
# signals and properties.
# e.g. GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_builddir) $(GTK_DEBUG_FLAGS)
# e.g. GTKDOC_LIBS=$(top_builddir)/gtk/$(gtktargetlib)
GTKDOC_CFLAGS=-I$(top_srcdir) -I$(top_srcdir)/src
GTKDOC_LIBS=$(top_builddir)/src/libmatrix-glib-0.0.la
# This includes the standard gtk-doc make rules, copied by gtkdocize.
include $(top_srcdir)/gtk-doc.make
# Comment this out if you want 'make check' to test you doc status
# and run some sanity checks
if ENABLE_GTK_DOC
TESTS_ENVIRONMENT = \
DOC_MODULE=$(DOC_MODULE) DOC_MAIN_SGML_FILE=$(DOC_MAIN_SGML_FILE) \
SRCDIR=$(abs_srcdir) BUILDDIR=$(abs_builddir)
TESTS = $(GTKDOC_CHECK)
endif
-include $(top_srcdir)/git.mk

View File

@@ -0,0 +1,98 @@
<?xml version="1.0"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd"
[
<!ENTITY % local.common.attrib "xmlns:xi CDATA #FIXED 'http://www.w3.org/2003/XInclude'">
<!ENTITY % gtkdocentities SYSTEM "xml/gtkdocentities.ent">
%gtkdocentities;
]>
<book id="index">
<bookinfo>
<title>&package_name; Reference Manual</title>
<releaseinfo>
for &package_string;.
The latest version of this documentation can be found on-line at
<ulink role="online-location" url="http://[SERVER]/&package_name;/index.html">http://[SERVER]/&package_name;/</ulink>.
</releaseinfo>
</bookinfo>
<chapter id="matrix-glib-sdk-basic-types">
<title>Basic types</title>
<xi:include href="xml/matrix-enumtypes.xml"/>
<xi:include href="xml/matrix-compacts.xml"/>
<xi:include href="xml/matrix-profile.xml"/>
<xi:include href="xml/matrix-room.xml"/>
<xi:include href="xml/matrix-types.xml"/>
<xi:include href="xml/matrix-version.xml"/>
</chapter>
<chapter id="matrix-glib-sdk-events">
<title>Event types</title>
<xi:include href="xml/event-handling.xml"/>
<xi:include href="xml/matrix-event-base.xml"/>
<xi:include href="xml/matrix-event-call-base.xml"/>
<xi:include href="xml/matrix-event-call-answer.xml"/>
<xi:include href="xml/matrix-event-call-candidates.xml"/>
<xi:include href="xml/matrix-event-call-hangup.xml"/>
<xi:include href="xml/matrix-event-call-invite.xml"/>
<xi:include href="xml/matrix-event-presence.xml"/>
<xi:include href="xml/matrix-event-receipt.xml"/>
<xi:include href="xml/matrix-event-room-aliases.xml"/>
<xi:include href="xml/matrix-event-room-avatar.xml"/>
<xi:include href="xml/matrix-event-room-base.xml"/>
<xi:include href="xml/matrix-event-room-canonical-alias.xml"/>
<xi:include href="xml/matrix-event-room-create.xml"/>
<xi:include href="xml/matrix-event-room-guest-access.xml"/>
<xi:include href="xml/matrix-event-room-history-visibility.xml"/>
<xi:include href="xml/matrix-event-room-join-rules.xml"/>
<xi:include href="xml/matrix-event-room-member.xml"/>
<xi:include href="xml/matrix-event-room-message.xml"/>
<xi:include href="xml/matrix-event-room-message-feedback.xml"/>
<xi:include href="xml/matrix-event-room-name.xml"/>
<xi:include href="xml/matrix-event-room-power-levels.xml"/>
<xi:include href="xml/matrix-event-room-redaction.xml"/>
<xi:include href="xml/matrix-event-room-third-party-invite.xml"/>
<xi:include href="xml/matrix-event-room-topic.xml"/>
<xi:include href="xml/matrix-event-state-base.xml"/>
<xi:include href="xml/matrix-event-tag.xml"/>
<xi:include href="xml/matrix-event-typing.xml"/>
</chapter>
<chapter id="matrix-glib-sdk-messages">
<title>Message types</title>
<xi:include href="xml/message-handling.xml"/>
<xi:include href="xml/matrix-message-base.xml"/>
<xi:include href="xml/matrix-message-text.xml"/>
<xi:include href="xml/matrix-message-emote.xml"/>
<xi:include href="xml/matrix-message-notice.xml"/>
<xi:include href="xml/matrix-message-file.xml"/>
<xi:include href="xml/matrix-message-audio.xml"/>
<xi:include href="xml/matrix-message-image.xml"/>
<xi:include href="xml/matrix-message-video.xml"/>
<xi:include href="xml/matrix-message-location.xml"/>
</chapter>
<chapter>
<title>Communicating with homeservers</title>
<xi:include href="xml/matrix-api.xml"/>
<xi:include href="xml/matrix-client.xml"/>
<xi:include href="xml/matrix-http-api.xml"/>
<xi:include href="xml/matrix-http-client.xml"/>
</chapter>
<chapter id="object-tree">
<title>Object Hierarchy</title>
<xi:include href="xml/tree_index.sgml"/>
</chapter>
<index id="api-index-full">
<title>API Index</title>
<xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
</index>
<index id="deprecated-api-index" role="deprecated">
<title>Index of deprecated API</title>
<xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include>
</index>
<xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
</book>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +0,0 @@
SUBDIRS =
if ENABLE_GTK_DOCS
SUBDIRS += gtk-doc
endif

View File

@@ -1,28 +0,0 @@
include $(top_srcdir)/vala-globals.mk
CLEANFILES =
sources = $(top_srcdir)/src/*.vala
gtkdocdir = $(datadir)/gtk-doc/html/matrix-glib
gtkdoc_DATA = \
gtk-doc/matrix-glib/*.txt \
gtk-doc/matrix-glib/*.xml \
gtk-doc/matrix-glib/xml/*.xml \
gtk-doc/matrix-glib/xml/*.top \
gtk-doc/matrix-glib/xml/*.bottom \
gtk-doc/matrix-glib/*.types \
gtk-doc/matrix-glib/sgml.stamp \
$(NULL)
$(gtkdoc_DATA): matrix-glib-gtk-doc
matrix-glib-gtk-doc:
$(VALADOC) -o gtk-doc/matrix-glib --doclet=gtkdoc \
-X $(top_builddir)/src/matrix-glib.h \
$(VALADOC_FLAGS) $(sources)
all: matrix-glib-gtk-doc
clean-local:
rm -rf gtk-doc
rm -rf matrix-glib

227
git.mk Normal file
View File

@@ -0,0 +1,227 @@
# git.mk
#
# Copyright 2009, Red Hat, Inc.
# Copyright 2010,2011 Behdad Esfahbod
# Written by Behdad Esfahbod
#
# Copying and distribution of this file, with or without modification,
# is permitted in any medium without royalty provided the copyright
# notice and this notice are preserved.
#
# The latest version of this file can be downloaded from:
# https://raw.github.com/behdad/git.mk/master/git.mk
# Bugs, etc, should be reported upstream at:
# https://github.com/behdad/git.mk
#
# To use in your project, import this file in your git repo's toplevel,
# then do "make -f git.mk". This modifies all Makefile.am files in
# your project to -include git.mk. Remember to add that line to new
# Makefile.am files you create in your project, or just rerun the
# "make -f git.mk".
#
# This enables automatic .gitignore generation. If you need to ignore
# more files, add them to the GITIGNOREFILES variable in your Makefile.am.
# But think twice before doing that. If a file has to be in .gitignore,
# chances are very high that it's a generated file and should be in one
# of MOSTLYCLEANFILES, CLEANFILES, DISTCLEANFILES, or MAINTAINERCLEANFILES.
#
# The only case that you need to manually add a file to GITIGNOREFILES is
# when remove files in one of mostlyclean-local, clean-local, distclean-local,
# or maintainer-clean-local make targets.
#
# Note that for files like editor backup, etc, there are better places to
# ignore them. See "man gitignore".
#
# If "make maintainer-clean" removes the files but they are not recognized
# by this script (that is, if "git status" shows untracked files still), send
# me the output of "git status" as well as your Makefile.am and Makefile for
# the directories involved and I'll diagnose.
#
# For a list of toplevel files that should be in MAINTAINERCLEANFILES, see
# Makefile.am.sample in the git.mk git repo.
#
# Don't EXTRA_DIST this file. It is supposed to only live in git clones,
# not tarballs. It serves no useful purpose in tarballs and clutters the
# build dir.
#
# This file knows how to handle autoconf, automake, libtool, gtk-doc,
# gnome-doc-utils, yelp.m4, mallard, intltool, gsettings, dejagnu.
#
# This makefile provides the following targets:
#
# - all: "make all" will build all gitignore files.
# - gitignore: makes all gitignore files in the current dir and subdirs.
# - .gitignore: make gitignore file for the current dir.
# - gitignore-recurse: makes all gitignore files in the subdirs.
#
# KNOWN ISSUES:
#
# - Recursive configure doesn't work as $(top_srcdir)/git.mk inside the
# submodule doesn't find us. If you have configure.{in,ac} files in
# subdirs, add a proxy git.mk file in those dirs that simply does:
# "include $(top_srcdir)/../git.mk". Add more ..'s to your taste.
# And add those files to git. See vte/gnome-pty-helper/git.mk for
# example.
#
git-all: git-mk-install
git-mk-install:
@echo Installing git makefile
@any_failed=; \
find "`test -z "$(top_srcdir)" && echo . || echo "$(top_srcdir)"`" -name Makefile.am | while read x; do \
if grep 'include .*/git.mk' $$x >/dev/null; then \
echo $$x already includes git.mk; \
else \
failed=; \
echo "Updating $$x"; \
{ cat $$x; \
echo ''; \
echo '-include $$(top_srcdir)/git.mk'; \
} > $$x.tmp || failed=1; \
if test x$$failed = x; then \
mv $$x.tmp $$x || failed=1; \
fi; \
if test x$$failed = x; then : else \
echo Failed updating $$x; >&2 \
any_failed=1; \
fi; \
fi; done; test -z "$$any_failed"
.PHONY: git-all git-mk-install
### .gitignore generation
$(srcdir)/.gitignore: Makefile.am $(top_srcdir)/git.mk
$(AM_V_GEN) \
{ \
if test "x$(DOC_MODULE)" = x -o "x$(DOC_MAIN_SGML_FILE)" = x; then :; else \
for x in \
$(DOC_MODULE)-decl-list.txt \
$(DOC_MODULE)-decl.txt \
tmpl/$(DOC_MODULE)-unused.sgml \
"tmpl/*.bak" \
xml html \
; do echo /$$x; done; \
fi; \
if test "x$(DOC_MODULE)$(DOC_ID)" = x -o "x$(DOC_LINGUAS)" = x; then :; else \
for lc in $(DOC_LINGUAS); do \
for x in \
$(if $(DOC_MODULE),$(DOC_MODULE).xml) \
$(DOC_PAGES) \
$(DOC_INCLUDES) \
; do echo /$$lc/$$x; done; \
done; \
for x in \
$(_DOC_OMF_ALL) \
$(_DOC_DSK_ALL) \
$(_DOC_HTML_ALL) \
$(_DOC_MOFILES) \
$(DOC_H_FILE) \
"*/.xml2po.mo" \
"*/*.omf.out" \
; do echo /$$x; done; \
fi; \
if test "x$(HELP_ID)" = x -o "x$(HELP_LINGUAS)" = x; then :; else \
for lc in $(HELP_LINGUAS); do \
for x in \
$(HELP_FILES) \
"$$lc.stamp" \
"$$lc.mo" \
; do echo /$$lc/$$x; done; \
done; \
fi; \
if test "x$(gsettings_SCHEMAS)" = x; then :; else \
for x in \
$(gsettings_SCHEMAS:.xml=.valid) \
$(gsettings__enum_file) \
; do echo /$$x; done; \
fi; \
if test -f $(srcdir)/po/Makefile.in.in; then \
for x in \
po/Makefile.in.in \
po/Makefile.in \
po/Makefile \
po/POTFILES \
po/stamp-it \
po/.intltool-merge-cache \
"po/*.gmo" \
"po/*.mo" \
po/$(GETTEXT_PACKAGE).pot \
intltool-extract.in \
intltool-merge.in \
intltool-update.in \
; do echo /$$x; done; \
fi; \
if test -f $(srcdir)/configure; then \
for x in \
autom4te.cache \
configure \
config.h \
stamp-h1 \
libtool \
config.lt \
; do echo /$$x; done; \
fi; \
if test "x$(DEJATOOL)" = x; then :; else \
for x in \
$(DEJATOOL) \
; do echo /$$x.sum; echo /$$x.log; done; \
echo /site.exp; \
fi; \
for x in \
.gitignore \
$(GITIGNOREFILES) \
$(CLEANFILES) \
$(PROGRAMS) $(check_PROGRAMS) $(EXTRA_PROGRAMS) \
$(LIBRARIES) $(check_LIBRARIES) $(EXTRA_LIBRARIES) \
$(LTLIBRARIES) $(check_LTLIBRARIES) $(EXTRA_LTLIBRARIES) \
so_locations \
.libs _libs \
$(MOSTLYCLEANFILES) \
"*.$(OBJEXT)" \
"*.lo" \
$(DISTCLEANFILES) \
$(am__CONFIG_DISTCLEAN_FILES) \
$(CONFIG_CLEAN_FILES) \
TAGS ID GTAGS GRTAGS GSYMS GPATH tags \
"*.tab.c" \
$(MAINTAINERCLEANFILES) \
$(BUILT_SOURCES) \
$(DEPDIR) \
Makefile \
Makefile.in \
"*.orig" \
"*.rej" \
"*.bak" \
"*~" \
".*.sw[nop]" \
".dirstamp" \
; do echo /$$x; done; \
} | \
sed "s@^/`echo "$(srcdir)" | sed 's/\(.\)/[\1]/g'`/@/@" | \
sed 's@/[.]/@/@g' | \
LC_ALL=C sort | uniq > $@.tmp && \
mv $@.tmp $@;
all: $(srcdir)/.gitignore gitignore-recurse-maybe
gitignore: $(srcdir)/.gitignore gitignore-recurse
gitignore-recurse-maybe:
@for subdir in $(DIST_SUBDIRS); do \
case " $(SUBDIRS) " in \
*" $$subdir "*) :;; \
*) test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) .gitignore gitignore-recurse-maybe || echo "Skipping $$subdir");; \
esac; \
done
gitignore-recurse:
@for subdir in $(DIST_SUBDIRS); do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) .gitignore gitignore-recurse || echo "Skipping $$subdir"); \
done
maintainer-clean: gitignore-clean
gitignore-clean:
-rm -f $(srcdir)/.gitignore
.PHONY: gitignore-clean gitignore gitignore-recurse gitignore-recurse-maybe

View File

@@ -1,68 +1,13 @@
include $(top_srcdir)/vala-globals.mk AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Matrix-GLib\" -D__MATRIX_GLIB_SDK_COMPILATION
AM_CPPFLAGS = -DG_LOG_DOMAIN=\"Matrix-GLib\"
# Empty variables for elements to be added later # Empty variables for elements to be added later
CLEANFILES = CLEANFILES =
BUILT_SOURCES = BUILT_SOURCES =
EXTRA_DIST = EXTRA_DIST =
AM_VALAFLAGS =
# Name of the public header file
PUBLIC_HEADER = matrix-glib.h
# Libraries to create # Libraries to create
lib_LTLIBRARIES = libmatrix-glib-0.0.la lib_LTLIBRARIES = libmatrix-glib-0.0.la
# Vala source files
libmatrix_glib_0_0_la_VALA_SOURCES = \
namespace-info.vala \
matrix-api.vala \
matrix-client.vala \
matrix-types.vala \
matrix-http-api.vala \
matrix-http-client.vala \
matrix-compacts.vala \
matrix-event-base.vala \
matrix-event-room-base.vala \
matrix-event-state-base.vala \
matrix-event-presence.vala \
matrix-event-room-member.vala \
matrix-event-room-message.vala \
matrix-event-room-topic.vala \
matrix-event-typing.vala \
matrix-event-room-aliases.vala \
matrix-event-receipt.vala \
matrix-event-room-history-visibility.vala \
matrix-event-room-join-rules.vala \
matrix-event-room-name.vala \
matrix-event-tag.vala \
matrix-event-room-canonical-alias.vala \
matrix-event-room-create.vala \
matrix-event-room-power-levels.vala \
matrix-event-room-avatar.vala \
matrix-event-room-message-feedback.vala \
matrix-event-room-guest-access.vala \
matrix-event-room-redaction.vala \
matrix-event-room-third-party-invite.vala \
matrix-event-call-base.vala \
matrix-event-call-invite.vala \
matrix-event-call-candidates.vala \
matrix-event-call-answer.vala \
matrix-event-call-hangup.vala \
matrix-message-base.vala \
matrix-message-text.vala \
matrix-message-emote.vala \
matrix-message-notice.vala \
matrix-message-file.vala \
matrix-message-image.vala \
matrix-message-audio.vala \
matrix-message-video.vala \
matrix-message-location.vala \
matrix-profile.vala \
matrix-room.vala \
$(NULL)
AM_CPPFLAGS += \ AM_CPPFLAGS += \
-include $(CONFIG_HEADER) \ -include $(CONFIG_HEADER) \
-I$(top_srcdir) \ -I$(top_srcdir) \
@@ -72,50 +17,65 @@ AM_CPPFLAGS += \
$(GOBJECT_CFLAGS) \ $(GOBJECT_CFLAGS) \
$(SOUP_CFLAGS) \ $(SOUP_CFLAGS) \
$(JSON_CFLAGS) \ $(JSON_CFLAGS) \
$(VALA_CFLAGS) \
$(NULL) $(NULL)
AM_VALAFLAGS += \
--library=Matrix-$(MATRIX_GLIB_API_VERSION) \
$(VALA_PKG_LIST) \
--vapi=Matrix-$(MATRIX_GLIB_API_VERSION).vapi \
-H $(PUBLIC_HEADER) \
-C \
--use-header \
--gir=Matrix-$(MATRIX_GLIB_API_VERSION).gir \
--vapidir=$(top_srcdir)/vapi \
$(NULL)
vala-stamp: $(libmatrix_glib_0_0_la_VALA_SOURCES)
@rm -f vala-temp
@touch vala-temp
$(AM_V_GEN) $(VALAC) $(AM_VALAFLAGS) $^
@mv -f vala-temp $@
CLEANFILES += \
$(PUBLIC_HEADER) \
$(libmatrix_glib_0_0_la_VALA_SOURCES:.vala=.c) \
$(NULL)
$(libmatrix_glib_0_0_la_VALA_SOURCES:.vala=.c): vala-stamp
@if test -f $@; then :; else \
trap 'rm -rf vala-lock vala-stamp' 1 2 13 15; \
if mkdir vala-lock 2> /dev/null; then \
rm -f vala-stamp; \
$(MAKE) $(AM_MAKEFLAGS) vala-stamp; \
rmdir vala-lock; \
else \
while test -d vala-lock; do sleep 1; done; \
test -f vala-stamp; exit $$?; \
fi \
fi
# Binaries to create # Binaries to create
bin_PROGRAMS = test-api-client test-client bin_PROGRAMS = test-api-client test-client
EVENT_H_FILES = \
matrix-event-base.h \
matrix-event-call-base.h \
matrix-event-call-answer.h \
matrix-event-call-hangup.h \
matrix-event-call-invite.h \
matrix-event-call-candidates.h \
$(NULL)
MESSAGE_H_FILES = \
matrix-message-base.h \
matrix-message-text.h \
matrix-message-location.h \
matrix-message-emote.h \
matrix-message-file.h \
matrix-message-image.h \
matrix-message-audio.h \
matrix-message-video.h \
matrix-message-notice.h \
matrix-event-room-base.h \
matrix-event-state-base.h \
matrix-event-tag.h \
matrix-event-presence.h \
matrix-event-room-member.h \
matrix-event-room-topic.h \
matrix-event-room-aliases.h \
matrix-event-room-avatar.h \
matrix-event-room-name.h \
matrix-event-room-message.h \
matrix-event-room-history-visibility.h \
matrix-event-room-join-rules.h \
matrix-event-room-canonical-alias.h \
matrix-event-room-create.h \
matrix-event-room-power-levels.h \
matrix-event-room-guest-access.h \
matrix-event-room-message-feedback.h \
matrix-event-room-redaction.h \
matrix-event-room-third-party-invite.h \
matrix-event-typing.h \
matrix-event-receipt.h \
$(NULL)
INST_H_SRC_FILES = \ INST_H_SRC_FILES = \
matrix-c-types.h \ matrix-types.h \
matrix-compacts.h \
matrix-api.h \
matrix-http-api.h \
matrix-client.h \
matrix-http-client.h \
$(EVENT_H_FILES) \
$(MESSAGE_H_FILES) \
utils.h \ utils.h \
matrix-profile.h \
matrix-room.h \
$(NULL) $(NULL)
INST_H_BUILT_FILES = \ INST_H_BUILT_FILES = \
@@ -125,16 +85,58 @@ INST_H_BUILT_FILES = \
$(NULL) $(NULL)
matrix_enum_headers = \ matrix_enum_headers = \
matrix-c-types.h \ matrix-types.h \
$(NULL) $(NULL)
libmatrix_glib_0_0_la_SOURCES = \ libmatrix_glib_0_0_la_SOURCES = \
$(INST_H_BUILT_FILES) \ $(INST_H_BUILT_FILES) \
matrix-marshalers.c \ matrix-marshalers.c \
$(libmatrix_glib_0_0_la_VALA_SOURCES:.vala=.c) \
matrix-event-types.c \ matrix-event-types.c \
matrix-version.c \ matrix-version.c \
matrix-c-types.c \ matrix-api.c \
matrix-http-api.c \
matrix-client.c \
matrix-http-client.c \
matrix-types.c \
matrix-compacts.c \
matrix-event-base.c \
matrix-event-call-base.c \
matrix-event-call-answer.c \
matrix-event-call-hangup.c \
matrix-event-call-invite.c \
matrix-event-call-candidates.c \
matrix-message-base.c \
matrix-message-text.c \
matrix-message-location.c \
matrix-message-emote.c \
matrix-message-file.c \
matrix-message-image.c \
matrix-message-audio.c \
matrix-message-video.c \
matrix-message-notice.c \
matrix-event-tag.c \
matrix-event-presence.c \
matrix-event-room-member.c \
matrix-event-typing.c \
matrix-event-room-base.c \
matrix-event-state-base.c \
matrix-event-receipt.c \
matrix-event-room-topic.c \
matrix-event-room-aliases.c \
matrix-event-room-avatar.c \
matrix-event-room-name.c \
matrix-event-room-message.c \
matrix-event-room-history-visibility.c \
matrix-event-room-join-rules.c \
matrix-event-room-canonical-alias.c \
matrix-event-room-create.c \
matrix-event-room-power-levels.c \
matrix-event-room-message-feedback.c \
matrix-event-room-redaction.c \
matrix-event-room-guest-access.c \
matrix-event-room-third-party-invite.c \
matrix-profile.c \
matrix-room.c \
utils.c \ utils.c \
matrix-enumtypes.c \ matrix-enumtypes.c \
$(INST_H_SRC_FILES) \ $(INST_H_SRC_FILES) \
@@ -157,15 +159,6 @@ libmatrix_glib_0_0_la_LIBADD = \
libmatrix_glib_0_0_la_LDFLAGS = \ libmatrix_glib_0_0_la_LDFLAGS = \
-version-info "$(LT_CURRENT)":"$(LT_REVISION)":"$(LT_AGE)" -version-info "$(LT_CURRENT)":"$(LT_REVISION)":"$(LT_AGE)"
$(PUBLIC_HEADER): vala-stamp
Matrix-0.0.vapi: libmatrix-glib-$(MATRIX_GLIB_API_VERSION).la
vapidir = $(datadir)/vala/vapi
dist_vapi_DATA = \
Matrix-$(MATRIX_GLIB_API_VERSION).vapi \
Matrix-$(MATRIX_GLIB_API_VERSION).deps \
$(NULL)
BUILT_SOURCES += \ BUILT_SOURCES += \
matrix-enumtypes.c \ matrix-enumtypes.c \
matrix-enumtypes.h \ matrix-enumtypes.h \
@@ -230,30 +223,60 @@ matrix-marshalers.c: matrix-marshalers.h
CLEANFILES += stamp-matrix-marshalers CLEANFILES += stamp-matrix-marshalers
limtatrix_glib_dlname = \ libmatrix_glib_dlname = \
`$(SED) -nE "s/^dlname='([A-Za-z0-9.+-]+)'/\1/p" libmatrix-glib-0.0.la`¬ `$(SED) -nE "s/^dlname='([A-Za-z0-9.+-]+)'/\1/p" libmatrix-glib-0.0.la`¬
INTROSPECTION_GIRS = Matrix-$(MATRIX_GLIB_API_VERSION).gir
INTROSPECTION_COMPILER_ARGS = --includedir=. $(libmatrix_glib_dlname)
Matrix-0.0.gir: libmatrix-glib-$(MATRIX_GLIB_API_VERSION).la if HAVE_INTROSPECTION
Matrix-0.0.typelib: $(INTROSPECTION_GIRS)
$(INTROSPECTION_COMPILER) $(INTROSPECTION_COMPILER_ARGS) $< -o $@ include $(INTROSPECTION_MAKEFILE)
INTROSPECTION_GIRS = \
Matrix-$(MATRIX_GLIB_API_VERSION).gir \
$(NULL)
Matrix-$(MATRIX_GLIB_API_VERSION).gir: libmatrix-glib-0.0.la
Matrix_0_0_gir_FILES = $(INST_H_SRC_FILE) $(INST_H_BUILT_FILES) $(filter %.c,$(libmatrix_glib_0_0_la_SOURCES))
Matrix_0_0_gir_LIBS = libmatrix-glib-0.0.la
Matrix_0_0_gir_SCANNERFLAGS = --identifier-prefix=Matrix --symbol-prefix=matrix --warn-all
Matrix_0_0_gir_INCLUDES = GLib-2.0 GObject-2.0
Matrix_0_0_gir_CFLAGS = -D_MATRIX_GLIB_SDK_COMPILATION -I$(top_srcdir) -I$(srcdir) -I$(builddir) $(AM_CPPFLAGS)
Matrix_0_0_gir_EXPORT_PACKAGES = MatrixGLib
girdir = $(INTROSPECTION_GIRDIR) girdir = $(INTROSPECTION_GIRDIR)
gir_DATA = $(INTROSPECTION_GIRS) gir_DATA = $(INTROSPECTION_GIRS)
typelibdir = $(INTROSPECTION_TYPELIBDIR) typelibdir = $(INTROSPECTION_TYPELIBDIR)
typelib_DATA = Matrix-$(MATRIX_GLIB_API_VERSION).typelib typelib_DATA = Matrix-$(MATRIX_GLIB_API_VERSION).typelib
CLEANFILES += $(gir_DATA) $(typelibs_DATA)
headerdir = $(includedir)/matrix-glib-$(MATRIX_GLIB_API_VERSION) headerdir = $(includedir)/matrix-glib-$(MATRIX_GLIB_API_VERSION)
header_DATA = \ header_DATA = \
$(PUBLIC_HEADER) \
$(INST_H_SRC_FILES) \ $(INST_H_SRC_FILES) \
$(INST_H_BUILT_FILES) \ $(INST_H_BUILT_FILES) \
$(NULL) $(NULL)
CLEANFILES += $(gir_DATA) $(typelibs_DATA)
if HAVE_VAPIGEN
include $(VAPIGEN_MAKEFILE)
VAPIGEN_VAPIS = Matrix-$(MATRIX_GLIB_API_VERSION).vapi
Matrix_0_0_vapi_DEPS = \
json-glib-1.0 \
gio-2.0 \
libsoup-2.4 \
$(NULL)
Matrix_0_0_vapi_GIRS = $(INTROSPECTION_GIRS)
Matrix_0_0_vapi_FILES = $(INTROSPECTION_GIRS)
vapidir = $(datadir)/vala/vapi
vapi_DATA = $(VAPIGEN_VAPIS)
endif
endif
pkgconfig_in = matrix-glib-$(MATRIX_GLIB_API_VERSION).pc.in pkgconfig_in = matrix-glib-$(MATRIX_GLIB_API_VERSION).pc.in
pkgconfigdir = $(libdir)/pkgconfig pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = $(pkgconfig_in:.in=) pkgconfig_DATA = $(pkgconfig_in:.in=)

2167
src/matrix-api.c Normal file

File diff suppressed because it is too large Load Diff

950
src/matrix-api.h Normal file
View File

@@ -0,0 +1,950 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_API_H__
# define __MATRIX_GLIB_SDK_API_H__
# include <glib-object.h>
# include <json-glib/json-glib.h>
# include "matrix-compacts.h"
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
# ifdef __MATRIX_GLIB_SDK_COMPILATION
# define MATRIX_DEPRECATED_FOR(f)
# else
# define MATRIX_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f)
# endif
# define MATRIX_TYPE_API matrix_api_get_type()
G_DECLARE_INTERFACE(MatrixAPI, matrix_api, MATRIX, API, GObject);
typedef void (*MatrixAPICallback)(MatrixAPI *api,
const gchar *content_type,
JsonNode *json_content,
GByteArray *raw_content,
GError *err,
gpointer user_data);
struct _MatrixAPIInterface {
GTypeInterface parent_iface;
void (*abort_pending)(MatrixAPI *api);
void (*get_3pids)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*add_3pid)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
gboolean bind_creds,
Matrix3PidCredential *threepid_creds,
GError **error);
void (*deactivate_account)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *session,
const gchar *login_type,
GError **error);
void (*change_password)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *new_password,
GError **error);
void (*whoami)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*get_profile)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
GError **error);
void (*get_avatar_url)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
GError **error);
void (*set_avatar_url)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *avatar_url,
GError **error);
void (*get_display_name)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
GError **error);
void (*set_display_name)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *display_name,
GError **error);
void (*register_account)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
MatrixAccountKind account_kind,
gboolean bind_email,
const gchar *username,
const gchar *password,
GError **error);
void (*register_account_email)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *id_server,
const gchar *client_secret,
const gchar *email,
guint send_attempt,
GError **error);
void (*set_account_data)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *room_id,
const gchar *event_type,
JsonNode *content,
GError **error);
void (*get_room_tags)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *room_id,
GError **error);
void (*delete_room_tag)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *room_id,
const gchar *tag,
GError **error);
void (*add_room_tag)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *room_id,
const gchar *tag,
JsonNode *content,
GError **error);
void (*whois)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
GError **error);
void (*versions)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*create_room)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
MatrixRoomPreset preset,
const gchar *room_name,
const gchar *room_alias,
const gchar *topic,
MatrixRoomVisibility visibility,
JsonNode *creation_content,
MatrixEventState **initial_state,
int initial_state_length1,
gchar **invitees,
int invitees_length1,
Matrix3PidCredential **invite_3pids,
int invite_3pids_length1,
GError **error);
void (*delete_room_alias)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_alias,
GError **error);
void (*get_joined_rooms)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*get_room_id)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_alias,
GError **error);
void (*create_room_alias)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *room_alias,
GError **error);
void (*event_stream)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *from_token,
gulong timeout,
GError **error);
void (*get_event)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *event_id,
GError **error);
void (*initial_sync)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
guint limit,
gboolean archived,
GError **error);
void (*get_event_context)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *event_id,
guint limit,
GError **error);
void (*initial_sync_room)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
GError **error);
void (*list_room_members)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
GError **error);
void (*list_room_messages)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *from_token,
MatrixEventDirection direction,
guint limit,
GError **error);
void (*send_event_receipt)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
MatrixReceiptType receipt_type,
const gchar *event_id,
JsonNode *receipt,
GError **error);
void (*redact_event)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *event_id,
const gchar *txn_id,
const gchar *reason,
GError **error);
void (*send_event)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *event_type,
const gchar *txn_id,
JsonNode *content,
GError **error);
void (*get_room_state)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *event_type,
const gchar *state_key,
GError **error);
void (*send_state_event)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *event_type,
const gchar *state_key,
JsonNode *content,
GError **error);
void (*notify_room_typing)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *room_id,
guint timeout,
gboolean typing,
GError **error);
void (*sync)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *filter_id,
MatrixFilter *filter,
const gchar *since,
gboolean full_state,
gboolean set_presence,
gulong timeout,
GError **error);
void (*create_filter)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
MatrixFilter *filter,
GError **error);
void (*download_filter)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
const gchar *filter_id,
GError **error);
void (*join_room_id_or_alias)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id_or_alias,
GError **error);
void (*ban_user)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *user_id,
const gchar *reason,
GError **error);
void (*forget_room)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
GError **error);
void (*invite_user_3rdparty)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
Matrix3PidCredential *credential,
GError **error);
void (*invite_user)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *user_id,
GError **error);
void (*join_room)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
GError **error);
void (*kick_user)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *user_id,
const gchar *reason,
GError **error);
void (*leave_room)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
GError **error);
void (*unban_user)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *room_id,
const gchar *user_id,
GError **error);
void (*login)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *login_type,
JsonNode *content,
GError **error);
void (*logout)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*get_presence_list)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
GError **error);
void (*update_presence_list)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
gchar **drop_ids,
int drop_ids_length1,
gchar **invite_ids,
int invite_ids_length1,
GError **error);
void (*get_presence)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
GError **error);
void (*set_presence)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *user_id,
MatrixPresence presence,
const gchar *status_message,
GError **error);
void (*list_public_rooms)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*get_pushers)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*update_pusher)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
MatrixPusher *pusher,
GError **error);
void (*get_notifications)(MatrixAPI *api,
const gchar *from_token,
guint limit,
const gchar *filter,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*get_pushrules)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*delete_pushrule)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
GError **error);
void (*get_pushrule)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
GError **error);
void (*add_pushrule)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
const gchar *before,
const gchar *after,
gchar **actions,
int actions_length1,
MatrixPusherConditionKind *conditions,
int conditions_length1,
GError **error);
void (*toggle_pushrule)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
gboolean enabled,
GError **error);
void (*search)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *next_batch,
MatrixSearchCategories *search_categories,
GError **error);
void (*get_turn_server)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*media_download)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *server_name,
const gchar *media_id,
GError **error);
void (*media_thumbnail)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *server_name,
const gchar *media_id,
guint width,
guint height,
MatrixResizeMethod method,
GError **error);
void (*media_upload)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
const gchar *content_type,
GByteArray *content,
GError **error);
void (*get_devices)(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void (*get_device)(MatrixAPI *api,
const gchar *device_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
const gchar *(*get_token)(MatrixAPI *api);
void (*set_token)(MatrixAPI *api, const gchar *value);
const gchar *(*get_user_id)(MatrixAPI *api);
void (*set_user_id)(MatrixAPI *api, const gchar *user_id);
const gchar *(*get_homeserver)(MatrixAPI *api);
void (*set_homeserver)(MatrixAPI *api, const gchar *homeserver);
};
void matrix_api_abort_pending(MatrixAPI *api);
void matrix_api_get_3pids(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_add_3pid(MatrixAPI *api,
gboolean bind_creds,
Matrix3PidCredential *threepid_creds,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_deactivate_account(MatrixAPI *api,
const gchar *session,
const gchar *login_type,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_change_password(MatrixAPI *api,
const gchar *new_password,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_whoami(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_profile(MatrixAPI *api,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_avatar_url(MatrixAPI *api,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_set_avatar_url(MatrixAPI *api,
const gchar *user_id,
const gchar *avatar_url,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_display_name(MatrixAPI *api,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_set_display_name(MatrixAPI *api,
const gchar *user_id,
const gchar *display_name,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_register_account(MatrixAPI *api,
MatrixAccountKind account_kind,
gboolean bind_email,
const gchar *username,
const gchar *password,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_register_account_email(MatrixAPI *api,
const gchar *id_server,
const gchar *client_secret,
const gchar *email,
guint send_attempt,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_set_account_data(MatrixAPI *api,
const gchar *user_id,
const gchar *room_id,
const gchar *event_type,
JsonNode *content,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_room_tags(MatrixAPI *api,
const gchar *user_id,
const gchar *room_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_delete_room_tag(MatrixAPI *api,
const gchar *user_id,
const gchar *room_id,
const gchar *tag,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_add_room_tag(MatrixAPI *api,
const gchar *user_id,
const gchar *room_id,
const gchar *tag,
JsonNode *content,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_whois(MatrixAPI *api,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_versions(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_create_room(MatrixAPI *api,
MatrixRoomPreset preset,
const gchar *room_name,
const gchar *room_alias,
const gchar *topic,
MatrixRoomVisibility visibility,
JsonNode *creation_content,
MatrixEventState **initial_state,
int n_initial_state,
gchar **invitees,
int n_invitees,
Matrix3PidCredential **invite_3pids,
int n_invite_3pids,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_delete_room_alias(MatrixAPI *api,
const gchar *room_alias,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_joined_rooms(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_room_id(MatrixAPI *api,
const gchar *room_alias,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_create_room_alias(MatrixAPI *api,
const gchar *room_id,
const gchar *room_alias,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_event_stream(MatrixAPI *api,
const gchar *from_token,
gulong timeout,
MatrixAPICallback callback,
gpointer user_data,
GError **error)
MATRIX_DEPRECATED_FOR(matrix_api_sync);
void matrix_api_get_event(MatrixAPI *api,
const gchar *event_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error)
MATRIX_DEPRECATED_FOR(matrix_api_sync);
void matrix_api_initial_sync(MatrixAPI *api,
guint limit,
gboolean archived,
MatrixAPICallback callback,
gpointer user_data,
GError **error)
MATRIX_DEPRECATED_FOR(matrix_api_sync);
void matrix_api_get_event_context(MatrixAPI *api,
const gchar *room_id,
const gchar *event_id,
guint limit,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_initial_sync_room(MatrixAPI *api,
const gchar *room_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error)
MATRIX_DEPRECATED_FOR(matrix_api_sync);
void matrix_api_list_room_members(MatrixAPI *api,
const gchar *room_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_list_room_messages(MatrixAPI *api,
const gchar *room_id,
const gchar *from_token,
MatrixEventDirection direction,
guint limit,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_send_event_receipt(MatrixAPI *api,
const gchar *room_id,
MatrixReceiptType receipt_type,
const gchar *event_id,
JsonNode *receipt,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_redact_event(MatrixAPI *api,
const gchar *room_id,
const gchar *event_id,
const gchar *txn_id,
const gchar *reason,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_send_event(MatrixAPI *api,
const gchar *room_id,
const gchar *event_type,
const gchar *txn_id,
JsonNode *content,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_room_state(MatrixAPI *api,
const gchar *room_id,
const gchar *event_type,
const gchar *state_key,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_send_state_event(MatrixAPI *api,
const gchar *room_id,
const gchar *event_type,
const gchar *state_key,
JsonNode *content,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_notify_room_typing(MatrixAPI *api,
const gchar *user_id,
const gchar *room_id,
guint timeout,
gboolean typing,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_sync(MatrixAPI *api,
const gchar *filter_id,
MatrixFilter *filter,
const gchar *since,
gboolean full_state,
gboolean set_presence,
gulong timeout,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_create_filter(MatrixAPI *api,
const gchar *user_id,
MatrixFilter *filter,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_download_filter(MatrixAPI *api,
const gchar *user_id,
const gchar *filter_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_join_room_id_or_alias(MatrixAPI *api,
const gchar *room_id_or_alias,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_ban_user(MatrixAPI *api,
const gchar *room_id,
const gchar *user_id,
const gchar *reason,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_forget_room(MatrixAPI *api,
const gchar *room_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_invite_user_3rdparty(MatrixAPI *api,
const gchar *room_id,
Matrix3PidCredential *credential,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_invite_user(MatrixAPI *api,
const gchar *room_id,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_join_room(MatrixAPI *api,
const gchar *room_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_kick_user(MatrixAPI *api,
const gchar *room_id,
const gchar *user_id,
const gchar *reason,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_leave_room(MatrixAPI *api,
const gchar *room_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_unban_user(MatrixAPI *api,
const gchar *room_id,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_login(MatrixAPI *api,
const gchar *login_type,
JsonNode *content,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_logout(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_presence_list(MatrixAPI *api,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_update_presence_list(MatrixAPI *api,
const gchar *user_id,
gchar **drop_ids,
int n_drop_ids,
gchar **invite_ids,
int n_invite_ids,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_presence(MatrixAPI *api,
const gchar *user_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_set_presence(MatrixAPI *api,
const gchar *user_id,
MatrixPresence presence,
const gchar *status_message,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_list_public_rooms(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_pushers(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_update_pusher(MatrixAPI *api,
MatrixPusher *pusher,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_notifications(MatrixAPI *api,
const gchar *from_token,
guint limit,
const gchar *filter,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_pushrules(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_delete_pushrule(MatrixAPI *api,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_pushrule(MatrixAPI *api,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_add_pushrule(MatrixAPI *api,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
const gchar *before,
const gchar *after,
gchar **actions,
int n_actions,
MatrixPusherConditionKind *conditions,
int n_conditions,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_toggle_pushrule(MatrixAPI *api,
const gchar *scope,
MatrixPusherKind kind,
const gchar *rule_id,
gboolean enabled,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_search(MatrixAPI *api,
const gchar *next_batch,
MatrixSearchCategories *search_categories,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_turn_server(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_media_download(MatrixAPI *api,
const gchar *server_name,
const gchar *media_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_media_thumbnail(MatrixAPI *api,
const gchar *server_name,
const gchar *media_id,
guint width,
guint height,
MatrixResizeMethod method,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_media_upload(MatrixAPI *api,
const gchar *content_type,
GByteArray *content,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_devices(MatrixAPI *api,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
void matrix_api_get_device(MatrixAPI *api,
const gchar *device_id,
MatrixAPICallback callback,
gpointer user_data,
GError **error);
const gchar *matrix_api_get_token(MatrixAPI *api);
void matrix_api_set_token(MatrixAPI *api, const gchar *token);
const gchar *matrix_api_get_user_id(MatrixAPI *api);
void matrix_api_set_user_id(MatrixAPI *api, const gchar *user_id);
const gchar *matrix_api_get_homeserver(MatrixAPI *api);
void matrix_api_set_homeserver(MatrixAPI *api, const gchar *homeserver);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_API_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -1,294 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-c-types.h"
/**
* SECTION:matrix-types
* @title: Generic types
* @short_description: Generic types for Matrix GLib SDK calls
*
* These are the generic types used by many SDK calls for communication with the homeserver.
*/
/**
* MatrixError:
* @MATRIX_ERROR_NONE: no error. You should never see this.
* @MATRIX_ERROR_COMMUNICATION_ERROR: there was a problem in communication (e.g. connection error)
* @MATRIX_ERROR_INCOMPLETE: the passed/generated data is incomplete
* @MATRIX_ERROR_BAD_REQUEST: the request is invalid
* @MATRIX_ERROR_BAD_RESPONSE: malformed response, or the response is not a JSON object
* @MATRIX_ERROR_INVALID_ROOM_ID: the provided string doesnt contain a valid room ID
* @MATRIX_ERROR_UNKNOWN_VALUE: the response from the Matrix.org server contains a value unknown
* to this library. These should be reported to the Matrix GLib SDK developers
* @MATRIX_ERROR_INVALID_TYPE: the provided type is invalid
* @MATRIX_ERROR_UNSUPPORTED: the operation is unsupported
* @MATRIX_ERROR_INVALID_FORMAT: the format of the JSON node is invalid (e.g. it is an array instead of an object)
* @MATRIX_ERROR_UNAVAILABLE: the requested data is not cached yet. Clients getting this message
* may go online by some means to get the data
* @MATRIX_ERROR_NOT_FOUND: the requested data (e.g. member of a room) can not be found
* @MATRIX_ERROR_ALREADY_EXISTS: the data to create (e.g. when adding a new member to a Room
* object) already exists
* @MATRIX_ERROR_M_MISSING_TOKEN: authorization token is missing from the request
* @MATRIX_ERROR_M_FORBIDDEN: access was forbidden (e.g. due to a missing/invalid token, or using
* a bad password during login)
* @MATRIX_ERROR_M_UNKNOWN: an error unknown to the Matrix homeserver
* @MATRIX_ERROR_M_UNKNOWN_TOKEN: the token provided is not known for the homeserver
* @MATRIX_ERROR_M_NOT_JSON: illegal request, the content is not valid JSON
* @MATRIX_ERROR_M_UNRECOGNIZED: the homeserver didn't understand the request
* @MATRIX_ERROR_M_UNAUTHORIZED: the request is unauthorized
* @MATRIX_ERROR_M_BAD_JSON: the JSON data is not in the required format
* @MATRIX_ERROR_M_USER_IN_USE: the specified username is in use
* @MATRIX_ERROR_M_ROOM_IN_USE: the specified room is in use
* @MATRIX_ERROR_M_BAD_PAGINATION: invalid pagination parameters
* @MATRIX_ERROR_M_BAD_STATE: invalid state event
* @MATRIX_ERROR_M_NOT_FOUND: the requested resource is not found
* @MATRIX_ERROR_M_GUEST_ACCESS_FORBIDDEN: guest access was requested, but ( it is forbidden
* @MATRIX_ERROR_M_LIMIT_EXCEEDED: the request was rate limited
* @MATRIX_ERROR_M_CAPTCHA_NEEDED: a captcha is needed to continue
* @MATRIX_ERROR_M_CAPTCHA_INVALID: the provided captcha is invalid
* @MATRIX_ERROR_M_MISSING_PARAM: a parameter is missing from the request
* @MATRIX_ERROR_M_TOO_LARGE: the request data is too large
* @MATRIX_ERROR_M_EXCLUSIVE: the desired user ID is in an exclusive namespace claimed by an
* application server
* @MATRIX_ERROR_M_THREEPID_AUTH_FAILED: 3rd party authentication failed
* @MATRIX_ERROR_M_THREEPID_IN_USE: the provided 3rd party ID is already in use
* @MATRIX_ERROR_M_INVALID_USERNAME: the given username is invalid
* @MATRIX_ERROR_UNSPECIFIED: no error code was sent by the homeserver. If you see this error,
* that usually indicates a homeserver bug
* @MATRIX_ERROR_UNKNOWN_ERROR: an error unknown to this library
*
* Matrix SDK error codes. The SDK maps most known error codes from homeservers, too; these are
* the MATRIX_ERROR_M_* codes.
*/
/**
* MATRIX_ERROR:
*
* Error domain for Matrix GLib SDK. See #GError for more information on error domains.
*/
/**
* matrix_error_quark:
*
* Gets the Matrix error #GQuark
*/
G_DEFINE_QUARK(matrix-error-quark, matrix_error);
/**
* MatrixAccountKind:
* @MATRIX_ACCOUNT_KIND_DEFAULT: use the server default (usually #MATRIX_ACCOUNT_KIND_USER)
* @MATRIX_ACCOUNT_KIND_USER: normal user
* @MATRIX_ACCOUNT_KIND_GUEST: guest user
*
* User account types.
*/
/**
* MatrixEventDirection:
* @MATRIX_EVENT_DIRECTION_FORWARD: list events after the specified one
* @MATRIX_EVENT_DIRECTION_BACKWARD: list events before the specified one
*
* Direction of events when requesting an event context.
*/
/**
* MatrixEventFormat:
* @MATRIX_EVENT_FORMAT_DEFAULT: event format will be omitted from the filter, so the server
* will use its default (usually #MATRIX_EVENT_FORMAT_FEDERATION)
* @MATRIX_EVENT_FORMAT_CLIENT: return the events in a format suitable for clients
* @MATRIX_EVENT_FORMAT_FEDERATION: return the raw event as receieved over federation
*
* Event format received when synchronizing.
*/
/**
* MatrixPresence:
* @MATRIX_PRESENCE_UNKNOWN: user's presence is unknown
* @MATRIX_PRESENCE_ONLINE: user is online
* @MATRIX_PRESENCE_OFFLINE: user is offline
* @MATRIX_PRESENCE_UNAVAILABLE: user is unavailable (i.e. busy)
* @MATRIX_PRESENCE_FREE_FOR_CHAT: user is free for chat
*
* Presence values for matrix_api_set_presence() and other presence related queries.
*/
/**
* MatrixPusherConditionKind:
* @MATRIX_PUSHER_CONDITION_KIND_EVENT_MATCH: glob pattern match on a field of the event.
* Requires a `key` and a `pattern` parameter
* @MATRIX_PUSHER_CONDITION_KIND_PROFILE_TAG: matches the profile tag of the device that the
* notification would be delivered to. Requires a `profile_tag` parameter
* @MATRIX_PUSHER_CONDITION_KIND_CONTAINS_DISPLAY_NAME: matches unencrypted messages where the
* content's body contains the owner's display name in that room.
* @MATRIX_PUSHER_CONDITION_KIND_ROOM_MEMBER_COUNT: matches the current number of members in the
* room. Requires an `is` parameter, which must be an integer, optionally prefixed by `==`,
* `<`, `>`, `<=` or `>=`. If the prefix is omitted, it defaults to `==`
*
* Condition types for pushers.
*/
/**
* MatrixPusherKind:
* @MATRIX_PUSHER_KIND_OVERRIDE: highest priority rules
* @MATRIX_PUSHER_KIND_SENDER: for (unencrypted) messages that match certain patterns
* @MATRIX_PUSHER_KIND_ROOM: for all messages for a given room. The rule ID of a room rule is
* always the ID of the room that it affects
* @MATRIX_PUSHER_KIND_CONTENT: for messages from a specific Matrix user ID. The rule ID of such
* rules is always the Matrix ID of the user whose messages they'd apply to
* @MATRIX_PUSHER_KIND_UNDERRIDE: lowest priority rules
*
* Pusher types.
*/
/**
* MatrixReceiptType:
* @MATRIX_RECEIPT_TYPE_READ: indicate that the message has been read
*
* Receipt types of acknowledgment.
*/
/**
* MatrixResizeMethod:
* @MATRIX_RESIZE_METHOD_DEFAULT: use the server default value
* @MATRIX_RESIZE_METHOD_CROP: crop thumbnail to the requested size
* @MATRIX_RESIZE_METHOD_SCALE: scale thumbnail to the requested size
*
* Resizing methods for matrix_api_media_thumbnail().
*/
/**
* MatrixRoomMembership:
* @MATRIX_ROOM_MEMBERSHIP_UNKNOWN: the membership sent by the server is unknown to this SDK
* @MATRIX_ROOM_MEMBERSHIP_INVITE: the user has been invited to join a room, but has not yet
* joined it. They may not participate in the room until they join
* @MATRIX_ROOM_MEMBERSHIP_JOIN: the user has joined the room (possibly after accepting an invite),
* and may participate in it
* @MATRIX_ROOM_MEMBERSHIP_LEAVE: the user was once joined to the room, but has since left
* (possibly by choice, or possibly by being kicked)
* @MATRIX_ROOM_MEMBERSHIP_BAN: the user has been banned from the room, and is no longer allowed
* to join it until they are un-banned from the room (by having their membership state set
* to a value other than MATRIX_ROOM_MEMBERSHIP_BAN)
* @MATRIX_ROOM_MEMBERSHIP_KNOCK: this is a reserved word, which currently has no meaning
*
* Room membership types.
*/
/**
* MatrixRoomPreset:
* @MATRIX_ROOM_PRESET_NONE: no preset
* @MATRIX_ROOM_PRESET_PRIVATE: preset for private rooms
* @MATRIX_ROOM_PRESET_TRUSTED_PRIVATE: same as private rooms, but all users get the same power
* level as the room creator
* @MATRIX_ROOM_PRESET_PUBLIC: preset for public rooms
*
* Preset values for matrix_api_create_room() calls.
*/
/**
* MatrixRoomVisibility:
* @MATRIX_ROOM_VISIBILITY_DEFAULT: use a server-assigned value (usually
* #MATRIX_ROOM_VISIBILITY_PRIVATE)
* @MATRIX_ROOM_VISIBILITY_PUBLIC: make the room visible in the public room list
* @MATRIX_ROOM_VISIBILITY_PRIVATE: hide the room from the public room list
*
* Visibility values for room creation. Not to be confused with join rules.
*/
/**
* MatrixJoinRules:
* @MATRIX_JOIN_RULES_UNKNOWN: a value unknown to this library
* @MATRIX_JOIN_RULES_PUBLIC: anyone can join
* @MATRIX_JOIN_RULES_INVITE: users may join upon invite
* @MATRIX_JOIN_RULES_PRIVATE: reserved word, not usable yet
* @MATRIX_JOIN_RULES_KNOCK: reserved word, not usable yet
*
* Room join rules.
*/
/**
* MatrixSearchOrder:
* @MATRIX_SEARCH_ORDER_RECENT: order messages as they arrived
* @MATRIX_SEARCH_ORDER_RANK: order messages by relevance
*
* Search ordering.
*/
/**
* MatrixSearchKey:
* @MATRIX_SEARCH_KEY_CONTENT_BODY: search in the body of a message
* @MATRIX_SEARCH_KEY_CONTENT_NAME: search in the name of rooms
* @MATRIX_SEARCH_KEY_CONTENT_TOPIC: search in the topic of rooms
*
* Search keys.
*/
/**
* MatrixSearchGroupBy:
* @MATRIX_SEARCH_GROUP_BY_NONE: no grouping
* @MATRIX_SEARCH_GROUP_BY_ROOM_ID: group by room ID
* @MATRIX_SEARCH_GROUP_BY_SENDER: group by sender
*
* Search grouping
*
* The client can request that the results are returned along with
* grouping information, e.g. grouped by room_id. In this case the
* response will contain a group entry for each distinct value of
* room_id. Each group entry contains at least a list of the
* event_ids that are in that group, as well as potentially other
* metadata about the group.
*/
/**
* MatrixHistoryVisibility:
* @MATRIX_HISTORY_VISIBILITY_UNKNOWN: represents a value unknown to this library
* @MATRIX_HISTORY_VISIBILITY_INVITED: only room members can see the room history, and only what
* happened after they got an invitation
* @MATRIX_HISTORY_VISIBILITY_JOINED: only room members can see the room history, and only what
* happened after they joined
* @MATRIX_HISTORY_VISIBILITY_SHARED: only room members can see the room history, but they see all
* of it
* @MATRIX_HISTORY_VISIBILITY_WORLD_READABLE: anyone can see the room history
*
* Room history visibility
*/
/**
* MatrixGuestAccess:
* @MATRIX_GUEST_ACCESS_UNKNOWN: represents a value unknown to this library
* @MATRIX_GUEST_ACCESS_CAN_JOIN: guest users are allowed to access the room
* @MATRIX_GUEST_ACCESS_FORBIDDEN: guest users are not allowed to access the room
*
* Room guest access
*/
/**
* MatrixCallOfferType:
* @MATRIX_CALL_OFFER_TYPE_UNKNOWN: represents a value unknown to this library
* @MATRIX_CALL_OFFER_TYPE_OFFER: call offer
*
* Call offer types
*/
/**
* MatrixCallAnswerType:
* @MATRIX_CALL_ANSWER_TYPE_UNKNOWN: represents a value unknown to this library
* @MATRIX_CALL_ANSWER_TYPE_ANSWER: call answer
*
* Call answer types
*/

496
src/matrix-client.c Normal file
View File

@@ -0,0 +1,496 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-client.h"
#include "matrix-marshalers.h"
/**
* SECTION:matrix-client
* @short_description: Interface for Matrix client implementations
* @title: Interface for Matrix client implementations
*/
enum {
SIGNAL_LOGIN_FINISHED,
SIGNAL_EVENT,
SIGNAL_POLLING_STARTED,
SIGNAL_POLLING_STOPPED,
NUM_SIGNALS
};
static guint matrix_client_signals[NUM_SIGNALS] = {0};
/**
* MatrixClientInterface:
* @login_with_password: the virtual function pointer for matrix_client_login_with_password()
* @register_with_password: the virtual function pointer for matrix_client_register_with_password()
* @logout: the virtual function pointer for matrix_client_logout()
* @begin_polling: the virtual function pointer for matrix_client_begin_polling()
* @stop_polling: the virtual function pointer for matrix_client_stop_polling()
* @get_user_profile: the virtual function pointer for matrix_client_get_user_profile()
* @get_user_presence: the virtual function pointer for matrix_client_get_user_presence()
* @get_room_by_id: the virtual function pointer for matrix_client_get_room_by_id()
* @get_room_by_alias: the virtual function pointer for matrix_client_get_room_by_alias()
* @send: the virtual function pointer for matrix_client_send()
* @save_state: the virtual function pointer for matrix_client_save_state()
* @load_state: the virtual function pointer for matrix_client_load_state()
* @login_finished: the class closure for the #MatrixClient::login-finished signal
* @event: the class closure for the #MatrixClient::event signal
*
* Base interface for client communication with a Matrix.org homeserver
*/
G_DEFINE_INTERFACE(MatrixClient, matrix_client, G_TYPE_OBJECT);
/**
* MatrixClientSendCallback:
* @client: the #MatrixClient that initiated the request
* @event_id: the event ID of the event just sent
* @error: (nullable): a #GError holding errors that happened during sending, if any
* @user_data: (nullable): user data set when event sending was initiated
*
* Callback function type for matrix_client_send().
*/
/**
* MatrixClientEventCallback:
* @client: the #MatrixClient that sent the signal
* @room_id: the room ID from which the event originated
* @raw_event: the raw event
* @matrix_event: (nullable): a #MatrixMessageBase derived object
* @user_data: (nullable): user data set when the signal was connected
*
* Callback function type for matrix_client_connect_event().
*
* @matrix_event may be unset if there was no message handler registered for the message type
* (using matrix_message_register_type()), or if the message couldnt be deserialised by the
* message handler.
*/
/**
* matrix_client_login_with_password:
* @client: a #MatrixClient
* @username: the username to login with
* @password: the password to use
* @error: a #GError, or %NULL to ignore errors
*
* Authenticate with the Matrix.org server with a username and password.
*/
void
matrix_client_login_with_password(MatrixClient *matrix_client, const gchar *username, const gchar *password, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->login_with_password(matrix_client, username, password, error);
}
/**
* matrix_client_register_with_password:
* @client: a #MatrixClient
* @username: the username to register. If omitted, the server will generate one
* @password: the password to use with the registration
* @error: a #GError, or %NULL to ignore errors
*
* Register @username with the homeserver as a normal user. Upon success, the user is registered
* and authenticated.
*
* Implementations must emit the #MatrixClient::login-finished signal when a response arrives.
*
* This method registers a normal user account. If you want to register a different kind of user,
* use matrix_api_register_account().
*/
void
matrix_client_register_with_password(MatrixClient *matrix_client, const gchar *username, const gchar *password, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->register_with_password(matrix_client, username, password, error);
}
/**
* matrix_client_logout:
* @client: an object implementing the #MatrixClient interface
* @error: a #GError, or %NULL to ignore errors
*
* Logout from the homeserver. As Matrix.org doesnt have such a concept, this cancels all ongoing
* requests and clears the authentication data (e.g. tokens).
*/
void
matrix_client_logout(MatrixClient *matrix_client, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->logout(matrix_client, error);
}
/**
* matrix_client_begin_polling:
* @client: an object implementing the #MatrixClient interface
* @error: a #GError, or %NULL to ignore errors
*
* Begin polling the event stream.
*/
void
matrix_client_begin_polling(MatrixClient *matrix_client, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->begin_polling(matrix_client, error);
}
/**
* matrix_client_stop_polling:
* @client: a #MatrixClient
* @cancel_ongoing: if %TRUE, ongoing requests will be cancelled, too
* @error: a #GError, or %NULL to ignore errors
*
* Stop polling the event stream. If @cancel_ongoing is %TRUE, ongoing requests will be cancelled,
* too.
*/
void
matrix_client_stop_polling(MatrixClient *matrix_client, gboolean cancel_ongoing, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->stop_polling(matrix_client, cancel_ongoing, error);
}
/**
* matrix_client_emit_login_finished:
* @client: a #MatrixClient
* @success: set to %TRUE if login was successful
*
* Convenience function to emit the #MatrixClient::login-finished signal.
*/
void
matrix_client_emit_login_finished(MatrixClient *matrix_client, gboolean success)
{
g_signal_emit(matrix_client, matrix_client_signals[SIGNAL_LOGIN_FINISHED], 0, success);
}
/**
* matrix_client_incoming_event:
* @client: an object implementing the #MatrixClient interface
* @room_id: the room the event is associated with
* @raw_event: the raw event
* @matrix_event: the event as a Matrix.Event
*
* Emits the #MatrixClient::event signal.
*/
void
matrix_client_incoming_event(MatrixClient *matrix_client, const gchar *room_id, JsonNode *raw_event, MatrixEventBase *matrix_event)
{
GQuark equark;
g_return_if_fail(raw_event != NULL);
if (matrix_event == NULL) {
equark = g_type_qname(MATRIX_EVENT_TYPE_BASE);
} else {
equark = g_type_qname(G_TYPE_FROM_INSTANCE((GObject*)matrix_event));
}
g_signal_emit(matrix_client, matrix_client_signals[SIGNAL_EVENT], equark, room_id, raw_event, matrix_event);
}
/**
* matrix_client_get_user_profile:
* @client: an object implementing the #MatrixClient interface
* @user_id: (not nullable): the user ID to get the profile for
* @room_id: (nullable): the room ID to get the profile from, or %NULL to get the global profile
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Get the profile of a user specified by @user_id. If @room_id is not %NULL, return the
* room-specific profile. If the users profile is not cached yet, @error is set to
* #MATRIX_ERROR_UNAVAILABLE.
*
* Returns: (nullable): a #MatrixProfile object
*/
MatrixProfile *
matrix_client_get_user_profile(MatrixClient *matrix_client, const gchar *user_id, const gchar *room_id, GError **error)
{
g_return_val_if_fail(matrix_client != NULL, NULL);
return MATRIX_CLIENT_GET_IFACE(matrix_client)->get_user_profile(matrix_client, user_id, room_id, error);
}
/**
* matrix_client_get_user_presence:
* @client: an object implementing the #MatrixClient interface
* @user_id: (not nullable): the user ID to get presence info for
* @room_id: (nullable): the room ID to get the presence info from, or %NULL to get the global
* presence info
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Get the presence state of a user specified by @user_id. If @room_id is %NULL, return the room
* specific presence state. If the user's presence state is not cached yet, @error is set to
* #MATRIX_ERROR_UNAVAILABLE.
*
* Returns: the presence of @user_id
*/
MatrixPresence
matrix_client_get_user_presence(MatrixClient *matrix_client, const gchar *user_id, const gchar *room_id, GError **error)
{
g_return_val_if_fail(matrix_client != NULL, 0);
return MATRIX_CLIENT_GET_IFACE(matrix_client)->get_user_presence(matrix_client, user_id, room_id, error);
}
/**
* matrix_client_get_room_by_id:
* @client: an object implementing the #MatrixClient interface
* @room_id: (not nullable): the room ID to get the room information for
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Get a room object by the room ID specified in @room_id. If room data is not cached yet, error
* is set to #MATRIX_ERROR_UNAVAILABLE and %NULL is returned.
*
* Returns: (nullable): a #MatrixRoom object corresponding to @room_id
*/
MatrixRoom *
matrix_client_get_room_by_id(MatrixClient *matrix_client, const gchar *room_id, GError **error)
{
g_return_val_if_fail(matrix_client != NULL, NULL);
return MATRIX_CLIENT_GET_IFACE(matrix_client)->get_room_by_id(matrix_client, room_id, error);
}
/**
* matrix_client_get_room_by_alias:
* @client: an object implementing the #MatrixClient interface
* @room_alias: (not nullable): a room alias
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Get a room object by the room alias specified in @room_alias. If room data is not cached yet,
* @error is set to #MATRIX_ERROR_UNAVAILABLE and %NULL is returned.
*
* Please note that this may be a lengthy operation, especially if there are many rooms with many
* aliases.
*
* Returns: (nullable): a #MatrixRoom object with @room_alias
*/
MatrixRoom *
matrix_client_get_room_by_alias(MatrixClient *matrix_client, const gchar *room_alias, GError **error)
{
g_return_val_if_fail(matrix_client != NULL, NULL);
return MATRIX_CLIENT_GET_IFACE(matrix_client)->get_room_by_alias(matrix_client, room_alias, error);
}
/**
* matrix_client_send:
* @client: a #MatrixClient
* @room_id: the room to send the event to
* @evt: the event to send
* @callback: the callback function to call when the request is finished
* @user_data: user data to pass to the callback function
* @txn_id: the transaction ID to be used during this request. In case of a state event, it will be
* untouched
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Send an event to the given room. This should use the correct endpoint (e.g. the
* `/room/{roomId}/send` or the `/room/{roomId}/state` API in case of a HTTP connection) depending
* on the event: if the event has a state key (there is a state_key key in the generated JSON),
* even if an empty one, it will use the latter.
*/
void
matrix_client_send(MatrixClient *matrix_client,
const gchar *room_id,
MatrixEventBase *evt,
gulong txn_id,
MatrixClientSendCallback cb,
gpointer user_data,
GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->send(matrix_client, room_id, evt, cb, user_data, txn_id, error);
}
/**
* matrix_client_save_state:
* @client: an object implementing the #MatrixClient interface
* @filename: the filename to save state info to
* @error: a #GError, or %NULL to ignore errors
*
* Save the client state to a file. This may include server addresses and credentials, too, so a
* secure storage is highly recommended.
*/
void
matrix_client_save_state(MatrixClient *matrix_client, const gchar *filename, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->save_state(matrix_client, filename, error);
}
/**
* matrix_client_load_state:
* @client: an object implementing the #MatrixClient interface
* @filename: the name of the file to load state from
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Load the state of the client, as saved by matrix_client_save_state().
*/
void
matrix_client_load_state(MatrixClient *matrix_client, const gchar *filename, GError **error)
{
g_return_if_fail(matrix_client != NULL);
MATRIX_CLIENT_GET_IFACE(matrix_client)->load_state(matrix_client, filename, error);
}
static void
matrix_client_real_login_finished(MatrixClient *matrix_client, gboolean success)
{}
static void
matrix_client_real_event(MatrixClient *matrix_client, const gchar *room_id, JsonNode *raw_event, MatrixEventBase *matrix_event)
{
g_return_if_fail(raw_event != NULL);
}
static void
matrix_client_default_init(MatrixClientInterface *iface)
{
static gboolean initialized = FALSE;
if (!initialized) {
initialized = TRUE;
iface->login_finished = matrix_client_real_login_finished;
iface->event = matrix_client_real_event;
/**
* MatrixClient::login-finished:
* @client: the #MatrixClient that emitted the signal
* @success: if %TRUE, login was successful
*
* This signal is a sign for a finished login request.
*
* Implementations are responsible for emitting this signal when they get a response for a
* login request.
*/
matrix_client_signals[SIGNAL_LOGIN_FINISHED] = g_signal_new(
"login-finished",
MATRIX_TYPE_CLIENT,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET(MatrixClientInterface, login_finished),
NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
/**
* MatrixClient::event:
* @client: the #MatrixClient that emitted the signal
* @room_id: the ID of the room associated with this event
* @raw_event: the raw event as a JSON object
* @matrix_event: the event as a #MatrixEventBase derived object
*
* This signal is a sign of an incoming event.
*
* It gets emitted for every event, regardless if it is handled by other event signals,
* before other signals.
*
* Implementations are responsible for emitting this signal when any kind of event arrives
* from the event stream or the history.
*/
matrix_client_signals[SIGNAL_EVENT] = g_signal_new(
"event",
MATRIX_TYPE_CLIENT,
G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
G_STRUCT_OFFSET(MatrixClientInterface, event),
NULL, NULL,
_matrix_marshal_VOID__STRING_BOXED_OBJECT,
G_TYPE_NONE, 3, G_TYPE_STRING, JSON_TYPE_NODE, MATRIX_EVENT_TYPE_BASE);
/**
* MatrixClient::polling-started:
* @client: the #MatrixClient that emitted the signal
*
* This signal is emitted when polling is started.
*/
matrix_client_signals[SIGNAL_POLLING_STARTED] = g_signal_new(
"polling-started",
MATRIX_TYPE_CLIENT,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
/**
* MatrixClient::polling-stopped:
* @client: the object that sent the signal
* @error: gets set to an actual error if polling is stopped due to one
*
* This signal gets invoked when polling is stopped due to any reason.
*/
matrix_client_signals[SIGNAL_POLLING_STOPPED] = g_signal_new(
"polling-stopped",
MATRIX_TYPE_CLIENT,
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
g_cclosure_marshal_VOID__BOXED,
G_TYPE_NONE, 1, G_TYPE_ERROR);
}
}
/**
* matrix_client_connect_event:
* @client: a #MatrixClient
* @event_gtype: the #GType of a #MatrixEventBase derived type
* @event_callback: the callback function to connect
* @user_data: user data passed to the callback function
* @destroy_notify: function to call on @user_data when it can be destroyed
*
* Connect a handler for events. If @event_gtype is #MATRIX_EVENT_TYPE_BASE, all events will be
* sent to the callback function, otherwise only events that match the specified event type.
*
* If @event_gtype is not derived from #MatrixEventBase, @callback wont get connected.
*/
void
matrix_client_connect_event(MatrixClient *client,
GType event_gtype,
MatrixClientEventCallback callback,
gpointer user_data,
GDestroyNotify destroy_notify)
{
GClosure *closure;
GQuark equark;
MatrixEventBaseClass *event_class = MATRIX_EVENT_BASE_CLASS(
g_type_class_ref(event_gtype));
guint event_signal_id = g_signal_lookup("event", MATRIX_TYPE_CLIENT);
if (!MATRIX_EVENT_IS_BASE_CLASS(event_class)) {
g_warning("Trying to connect to a type that is not derived from MatrixEvent");
g_type_class_unref(event_class);
return;
}
g_type_class_unref(event_class);
equark = g_type_qname(event_gtype);
closure = g_closure_ref(g_cclosure_new(G_CALLBACK(callback),
user_data,
(GClosureNotify)destroy_notify));
g_closure_set_marshal(closure,
_matrix_marshal_VOID__STRING_BOXED_OBJECT);
g_closure_sink(closure);
g_signal_connect_closure_by_id(client,
event_signal_id, equark,
closure, FALSE);
}

133
src/matrix-client.h Normal file
View File

@@ -0,0 +1,133 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_CLIENT_H__
# define __MATRIX_GLIB_SDK_CLIENT_H__
# include <glib-object.h>
# include "matrix-enumtypes.h"
# include "matrix-profile.h"
# include "matrix-room.h"
# include "matrix-event-base.h"
G_BEGIN_DECLS
# define MATRIX_TYPE_CLIENT matrix_client_get_type()
G_DECLARE_INTERFACE(MatrixClient, matrix_client, MATRIX, CLIENT, GObject);
typedef void (*MatrixClientSendCallback)(MatrixClient *client, const gchar *event_id, GError *error, void *user_data);
typedef void (*MatrixClientEventCallback)(MatrixClient *client, const gchar *room_id, JsonNode *raw_event, MatrixEventBase *matrix_event, void *user_data);
struct _MatrixClientInterface {
GTypeInterface parent_iface;
void (*login_with_password)(MatrixClient *client,
const gchar *username,
const gchar *password,
GError **error);
void (*register_with_password)(MatrixClient *client,
const gchar *username,
const gchar *password,
GError **error);
void (*logout)(MatrixClient *client, GError **error);
void (*begin_polling)(MatrixClient *client, GError **error);
void (*stop_polling)(MatrixClient *client, gboolean cancel_ongoing, GError **error);
MatrixProfile *(*get_user_profile)(MatrixClient *client,
const gchar *user_id,
const gchar *room_id,
GError **error);
MatrixPresence (*get_user_presence)(MatrixClient *client,
const gchar *user_id,
const gchar *room_id,
GError **error);
MatrixRoom *(*get_room_by_id)(MatrixClient *client, const gchar *room_id, GError **error);
MatrixRoom *(*get_room_by_alias)(MatrixClient *client,
const gchar *room_alias,
GError **error);
void (*send)(MatrixClient *client,
const gchar *room_id,
MatrixEventBase *evt,
MatrixClientSendCallback cb, void *cb_target,
gulong txn_id,
GError **error);
void (*save_state)(MatrixClient *client,
const gchar *filename,
GError **error);
void (*load_state)(MatrixClient *client,
const gchar *filename,
GError **error);
void (*login_finished)(MatrixClient *client, gboolean success);
void (*event)(MatrixClient *client,
const gchar *room_id,
JsonNode *raw_event,
MatrixEventBase *matrix_event);
};
GType matrix_client_get_type(void) G_GNUC_CONST;
void matrix_client_login_with_password(MatrixClient *client,
const gchar *username,
const gchar *password,
GError **error);
void matrix_client_register_with_password(MatrixClient *client,
const gchar *username,
const gchar *password,
GError **error);
void matrix_client_logout(MatrixClient *client, GError **error);
void matrix_client_begin_polling(MatrixClient *client, GError **error);
void matrix_client_stop_polling(MatrixClient *client, gboolean cancel_ongoing, GError **error);
void matrix_client_emit_login_finished(MatrixClient *client, gboolean success);
void matrix_client_incoming_event(MatrixClient *client,
const gchar *room_id,
JsonNode *raw_event,
MatrixEventBase *matrix_event);
void matrix_client_connect_event(MatrixClient *client,
GType event_gtype,
MatrixClientEventCallback event_callback,
gpointer user_data,
GDestroyNotify destroy_notify);
MatrixProfile *matrix_client_get_user_profile(MatrixClient *client,
const gchar *user_id,
const gchar *room_id,
GError **error);
MatrixPresence matrix_client_get_user_presence(MatrixClient *client,
const gchar *user_id,
const gchar *room_id,
GError **error);
MatrixRoom *matrix_client_get_room_by_id(MatrixClient *client,
const gchar *room_id,
GError **error);
MatrixRoom *matrix_client_get_room_by_alias(MatrixClient *client,
const gchar *room_alias,
GError **error);
void matrix_client_send(MatrixClient *client,
const gchar *room_id,
MatrixEventBase *evt,
gulong txn_id,
MatrixClientSendCallback callback,
gpointer user_data,
GError **error);
void matrix_client_save_state(MatrixClient *client, const gchar *filename, GError **error);
void matrix_client_load_state(MatrixClient *client, const gchar *filename, GError **error);
void matrix_client_connect_event(MatrixClient *client,
GType event_gtype,
MatrixClientEventCallback callback,
gpointer user_data,
GDestroyNotify destroy_notify);
G_END_DECLS
#endif /*__MATRIX_GLIB_SDK_CLIENT_H__ */

View File

@@ -1,287 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Base interface for client communication with a Matrix.org
* homeserver
*/
public interface Matrix.Client : GLib.Object {
/**
* This signal is a sign for a finished login request.
*
* Implementations are responsible for emitting this signal when
* they get a response for a login request.
*
* @param success if %TRUE, login was successful
*/
public virtual signal void
login_finished(bool success)
{}
/**
* This signal is a sign of an incoming event. It gets emitted for
* every signal, regardless if it is handled by other event
* signals, before other signals.
*
* Implementations are responsible for emitting this signal when
* any kind of event arrives from the event stream or the history.
*
* @param room_id the ID of the room associated with this event
* @param raw_event the raw event as a JSON object
* @param matrix_event the event as a {@link Matrix.Event}
*/
[Signal (detailed=true)]
public virtual signal void
@event(string? room_id,
Json.Node raw_event,
Matrix.Event.Base? matrix_event)
{}
/**
* This signal is emitted when polling is started.
*/
public signal void
polling_started();
/**
* This signal gets invoked when polling is stopped due to any
* reason.
*
* @param error gets set to an actual error if polling is stopped
* due to one
*/
public signal void
polling_stopped(GLib.Error? error);
/**
* Callback function delegate for the event signal.
*
* @param room_id the room the event associated with
* @param raw_event the event as a raw JSON object
* @param matrix_event the event as a Matrix.Event object
*/
public delegate void
EventCallback(Matrix.Client client,
string? room_id,
Json.Node raw_event,
Matrix.Event.Base? matrix_event);
/**
* Authenticate with the Matrix.org server with a username and
* password.
*
* @param username the username to login with
* @param password the password to use
*/
public abstract void
login_with_password(string username,
string password)
throws Matrix.Error;
/**
* Register @username with the homeserver as a normal user.
*
* Upon success, the user is registered and authenticated.
*
* Implementations must emit the login-finished signal when a
* response arrives.
*
* This method registers a normal user account. If you want to
* register a different kind of user, use
* matrix_api_register_account().
*
* @param username the username to register. If omitted, the
* server will generate one
* @param password the password to use with the registration
*/
public abstract void
register_with_password(string? username,
string password)
throws Matrix.Error;
/**
* Logout from the homeserver. As Matrix.org doesnt have such a
* concept, this cancels all ongoing requests and clears the
* authentication data (e.g. tokens).
*/
public abstract void
logout()
throws Matrix.Error;
/**
* Begin polling the event stream.
*/
public abstract void
begin_polling()
throws Matrix.Error;
/**
* Stop polling the event stream. If @param cancel_ongoing is
* {{{true}}}, ongoing requests will be cancelled, too.
*
* @param cancel_ongoing if {{{true}}}, ongoing requests will be
* cancelled, too
*/
public abstract void
stop_polling(bool cancel_ongoing)
throws Matrix.Error;
/**
* Convenience function to emits the login-finished signal.
*
* @param success set to {{{true}}} if login was successful
*/
public void
emit_login_finished(bool success)
{
login_finished(success);
}
/**
* Emits the #MatrixClient::event signal.
*
* @param room_id the room this event is associated with
* @param raw_event the raw event
* @param matrix_event the event as a Matrix.Event
*/
public void
incoming_event(string? room_id,
Json.Node raw_event,
Matrix.Event.Base? matrix_event)
{
Quark equark;
if (matrix_event == null) {
equark = typeof(Matrix.Event.Base).qname();
} else {
equark = matrix_event.get_type().qname();
}
this.@event[equark.to_string()](room_id, raw_event, matrix_event);
}
/**
* Connect a handler for events. If @param event_gtype is
* Matrix.Event, all events will be sent to the callback function,
* otherwise only events that match the specified event type.
*
* If @event_gtype is not derived from
* {@link Matrix.Event}, @param callback wont get connected.
*
* @param event_gtype the {@link GLib.Type} of a
* {@link Matrix.Event} derivative
* @param event_callback the allback function to connect
*/
public extern void
connect_event(GLib.Type event_gtype,
owned EventCallback event_callback);
/**
* Get the profile of a user specified by @param user_id.
* If @param room_id is not null, return the room-specific
* profile. If the user's profile is not cached yet,
* Matrix.Error.UNAVAILABLE is thrown.
*/
public abstract Profile?
get_user_profile(string user_id, string? room_id = null)
throws Matrix.Error;
/**
* Get the presence state of a user specified
* by @param user_id. If @param room_id is null, return
* the room specific presence state. If the user's presence
* state is not cached yet, Matrix.Error.UNAVAILABLE is
* thrown.
*/
public abstract Presence
get_user_presence(string user_id, string? room_id = null)
throws Matrix.Error;
/**
* Get a room object by the room ID specified in @param room_id.
* If room data is not cached yet, Matrix.Error.UNAVAILABLE is
* thrown.
*
* @param room_id the ID of a room
* @return a Matrix.Room object
*/
public abstract Room
get_room_by_id(string room_id)
throws Matrix.Error;
/**
* Get a room object by the room alias specified
* in @param room_alias. If room data is not cached yet,
* {@link Matrix.Error.UNAVAILABLE} is thrown.
*
* @param room_alias a room alias
* @return a Matrix.Room object
*/
public abstract Room
get_room_by_alias(string room_alias)
throws Matrix.Error;
/**
* Callback type for {@link Matrix.Client.send}.
*
* @param event_id the event_id returned by the server
* @param err an error raised during event sending, if any
*/
public delegate void
SendCallback(string? event_id, GLib.Error? err);
/**
* Send an event to the given room. This will use the
* /room/{roomId}/send or /room/{roomId}/state API depending on
* the event: if the event has a state key (there is a state_key
* key in the generated JSON), even if an empty one, it will use
* the latter.
*
* @param room_id the room to send the event to
* @param evt the event to send
* @param cb the callback function to call when the request is
* finished
* @param txn_id the transaction ID used by this request. In case
* of a state event, it will be untouched
*/
public abstract void
send(string room_id,
Matrix.Event.Base evt,
SendCallback? cb,
out ulong txn_id)
throws Matrix.Error;
/*
* Save the state of the client. Implementors can choose what they
* actually save, and in what format.
*
* @param filename the name of the file to save state to
*/
public abstract void
save_state(string filename)
throws Matrix.Error, GLib.Error;
/**
* Load the state of the client, as saved by save_state().
*
* @param filename the name of the file to load state from
*/
public abstract void
load_state(string filename)
throws Matrix.Error, GLib.Error;
}

3145
src/matrix-compacts.c Normal file

File diff suppressed because it is too large Load Diff

245
src/matrix-compacts.h Normal file
View File

@@ -0,0 +1,245 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_COMPACTS_H__
# define __MATRIX_GLIB_SDK_COMPACTS_H__
# include <glib-object.h>
# include <json-glib/json-glib.h>
# include "matrix-types.h"
G_BEGIN_DECLS
# define MATRIX_TYPE_JSON_COMPACT matrix_json_compact_get_type()
# define MATRIX_JSON_COMPACT(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_TYPE_JSON_COMPACT, MatrixJsonCompact))
# define MATRIX_JSON_COMPACT_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), MATRIX_TYPE_JSON_COMPACT, MatrixJsonCompactClass))
# define MATRIX_IS_JSON_COMPACT(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_TYPE_JSON_COMPACT))
# define MATRIX_IS_JSON_COMPACT_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), MATRIX_TYPE_JSON_COMPACT))
# define MATRIX_JSON_COMPACT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_TYPE_JSON_COMPACT, MatrixJsonCompactClass))
typedef struct _MatrixJsonCompactClass MatrixJsonCompactClass;
typedef struct _MatrixJsonCompact MatrixJsonCompact;
void matrix_json_compact_unref(MatrixJsonCompact *json_compact);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(MatrixJsonCompact, matrix_json_compact_unref);
struct _MatrixJsonCompact {
GTypeInstance parent_instance;
/* < private > */
volatile int refcount;
};
struct _MatrixJsonCompactClass {
GTypeClass parent_class;
void (*finalize)(MatrixJsonCompact *json_compact);
JsonNode *(*get_json_node)(MatrixJsonCompact *json_compact, GError **error);
};
GType matrix_json_compact_get_type(void) G_GNUC_CONST;
MatrixJsonCompact *matrix_json_compact_construct(GType object_type);
MatrixJsonCompact *matrix_json_compact_ref(MatrixJsonCompact *json_compact);
JsonNode *matrix_json_compact_get_json_node(MatrixJsonCompact *json_compact, GError **error);
gchar *matrix_json_compact_get_json_data(MatrixJsonCompact *json_compact, gsize *datalen, GError **error);
#define MATRIX_TYPE_FILTER_RULES matrix_filter_rules_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixFilterRules, matrix_filter_rules, MATRIX, FILTER_RULES, MatrixJsonCompact);
struct _MatrixFilterRulesClass {
MatrixJsonCompactClass parent_class;
};
MatrixFilterRules *matrix_filter_rules_new(void);
MatrixFilterRules *matrix_filter_rules_construct(GType object_type);
void matrix_filter_rules_set_limit(MatrixFilterRules *filter_rules, guint limit);
guint matrix_filter_rules_get_limit(MatrixFilterRules *filter_rules);
void matrix_filter_rules_set_types(MatrixFilterRules *filter_rules, gchar **types, int n_types);
gchar **matrix_filter_rules_get_types(MatrixFilterRules *filter_rules, int *n_types);
void matrix_filter_rules_set_excluded_types(MatrixFilterRules *filter_rules, gchar **excluded_types, int n_excluded_types);
gchar **matrix_filter_rules_get_excluded_types(MatrixFilterRules *filter_rules, int *n_excluded_types);
void matrix_filter_rules_set_senders(MatrixFilterRules *filter_rules, gchar **senders, int n_senders);
gchar **matrix_filter_rules_get_senders(MatrixFilterRules *filter_rules, int *n_senders);
void matrix_filter_rules_set_excluded_senders(MatrixFilterRules *filter_rules, gchar **excluded_senders, int n_excluded_senders);
gchar **matrix_filter_rules_get_excluded_senders(MatrixFilterRules *filter_rules, int *n_excluded_senders);
void matrix_filter_rules_set_rooms(MatrixFilterRules *filter_rules, gchar **rooms, int n_rooms);
gchar **matrix_filter_rules_get_rooms(MatrixFilterRules *filter_rules, int *n_rooms);
void matrix_filter_rules_set_excluded_rooms(MatrixFilterRules *filter_rules, gchar **excluded_rooms, int n_excluded_rooms);
gchar **matrix_filter_rules_get_excluded_rooms(MatrixFilterRules *filter_rules, int *n_excluded_rooms);
# define MATRIX_TYPE_ROOM_FILTER matrix_room_filter_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixRoomFilter, matrix_room_filter, MATRIX, ROOM_FILTER, MatrixJsonCompact)
struct _MatrixRoomFilterClass {
MatrixJsonCompactClass parent_class;
};
MatrixRoomFilter *matrix_room_filter_new(void);
MatrixRoomFilter *matrix_room_filter_construct(GType object_type);
gboolean matrix_room_filter_get_include_leave(MatrixRoomFilter *room_filter);
void matrix_room_filter_set_include_leave(MatrixRoomFilter *room_filter, gboolean include_leave);
MatrixFilterRules *matrix_room_filter_get_ephemeral(MatrixRoomFilter *room_filter);
void matrix_room_filter_set_ephemeral(MatrixRoomFilter *room_filter, MatrixFilterRules *ephemeral_rules);
MatrixFilterRules *matrix_room_filter_get_state(MatrixRoomFilter *room_filter);
void matrix_room_filter_set_state(MatrixRoomFilter *room_filter, MatrixFilterRules *state_rules);
MatrixFilterRules *matrix_room_filter_get_timeline(MatrixRoomFilter *room_filter);
void matrix_room_filter_set_timeline(MatrixRoomFilter *room_filter, MatrixFilterRules *timeline_rules);
# define MATRIX_TYPE_FILTER matrix_filter_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixFilter, matrix_filter, MATRIX, FILTER, MatrixJsonCompact);
struct _MatrixFilterClass {
MatrixJsonCompactClass parent_class;
};
MatrixFilter *matrix_filter_new(void);
MatrixFilter *matrix_filter_construct(GType object_type);
gchar **matrix_filter_get_event_fields(MatrixFilter *filter, int *n_event_fields);
void matrix_filter_set_event_fields(MatrixFilter *filter, gchar **event_fields, int n_event_fields);
MatrixEventFormat matrix_filter_get_event_format(MatrixFilter *filter);
void matrix_filter_set_event_format(MatrixFilter *filter, MatrixEventFormat event_format);
MatrixFilterRules *matrix_filter_get_presence_filter(MatrixFilter *filter);
void matrix_filter_set_presence_filter(MatrixFilter *filter, MatrixFilterRules *presence_filter);
MatrixRoomFilter *matrix_filter_get_room_filter(MatrixFilter *filter);
void matrix_filter_set_room_filter(MatrixFilter *filter, MatrixRoomFilter *room_filter);
# define MATRIX_TYPE_3PID_CREDENTIAL matrix_3pid_credential_get_type()
G_DECLARE_DERIVABLE_TYPE(Matrix3PidCredential, matrix_3pid_credential, MATRIX, 3PID_CREDENTIAL, MatrixJsonCompact);
struct _Matrix3PidCredentialClass {
MatrixJsonCompactClass parent_class;
};
Matrix3PidCredential *matrix_3pid_credential_new(void);
Matrix3PidCredential *matrix_3pid_credential_construct(GType object_type);
const gchar *matrix_3pid_credential_get_id_server(Matrix3PidCredential *credential);
void matrix_3pid_credential_set_id_server(Matrix3PidCredential *credential, const gchar *id_server);
const gchar *matrix_3pid_credential_get_session_id(Matrix3PidCredential *credential);
void matrix_3pid_credential_set_session_id(Matrix3PidCredential *credential, const gchar *session_id);
const gchar *matrix_3pid_credential_get_client_secret(Matrix3PidCredential *credential);
void matrix_3pid_credential_set_client_secret(Matrix3PidCredential *credential, const gchar *client_secret);
# define MATRIX_TYPE_PUSHER matrix_pusher_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixPusher, matrix_pusher, MATRIX, PUSHER, MatrixJsonCompact);
struct _MatrixPusherClass {
MatrixJsonCompactClass parent_class;
};
MatrixPusher *matrix_pusher_new(void);
MatrixPusher *matrix_pusher_construct(GType object_type);
const gchar *matrix_pusher_get_device_display_name(MatrixPusher *pusher);
void matrix_pusher_set_device_display_name(MatrixPusher *pusher, const gchar *device_display_name);
const gchar *matrix_pusher_get_app_display_name(MatrixPusher *pusher);
void matrix_pusher_set_app_display_name(MatrixPusher *pusher, const gchar *app_display_name);
const gchar *matrix_pusher_get_app_id(MatrixPusher *pusher);
void matrix_pusher_set_app_id(MatrixPusher *pusher, const gchar *app_id);
gboolean matrix_pusher_get_append(MatrixPusher *pusher);
void matrix_pusher_set_append(MatrixPusher *pusher, gboolean append);
const gchar *matrix_pusher_get_kind(MatrixPusher *pusher);
void matrix_pusher_set_kind(MatrixPusher *pusher, const gchar *kind);
const gchar *matrix_pusher_get_lang(MatrixPusher *pusher);
void matrix_pusher_set_lang(MatrixPusher *pusher, const gchar *lang);
const gchar *matrix_pusher_get_profile_tag(MatrixPusher *pusher);
void matrix_pusher_set_profile_tag(MatrixPusher *pusher, const gchar *profile_tag);
const gchar *matrix_pusher_get_pushkey(MatrixPusher *pusher);
void matrix_pusher_set_pushkey(MatrixPusher *pusher, const gchar *pushkey);
JsonNode *matrix_pusher_get_data(MatrixPusher *pusher);
void matrix_pusher_set_data(MatrixPusher *pusher, JsonNode *data);
# define MATRIX_TYPE_EVENT_CONTEXT matrix_event_context_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventContext, matrix_event_context, MATRIX, EVENT_CONTEXT, MatrixJsonCompact);
struct _MatrixEventContextClass {
MatrixJsonCompactClass parent_class;
};
MatrixEventContext *matrix_event_context_new (void);
MatrixEventContext *matrix_event_context_construct (GType object_type);
gint matrix_event_context_get_before_limit (MatrixEventContext *event_context);
void matrix_event_context_set_before_limit (MatrixEventContext *event_context, gint before_limit);
gint matrix_event_context_get_after_limit (MatrixEventContext *event_context);
void matrix_event_context_set_after_limit (MatrixEventContext *event_context, gint after_limit);
gboolean matrix_event_context_get_include_profile (MatrixEventContext *event_context);
void matrix_event_context_set_include_profile (MatrixEventContext *event_context, gboolean include_profile);
# define MATRIX_TYPE_SEARCH_GROUPING matrix_search_grouping_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixSearchGrouping, matrix_search_grouping, MATRIX, SEARCH_GROUPING, MatrixJsonCompact);
struct _MatrixSearchGroupingClass {
MatrixJsonCompactClass parent_class;
};
MatrixSearchGrouping *matrix_search_grouping_new(void);
MatrixSearchGrouping *matrix_search_grouping_construct(GType object_type);
MatrixSearchGroupBy matrix_search_grouping_get_key(MatrixSearchGrouping *search_grouping);
void matrix_search_grouping_set_key(MatrixSearchGrouping *search_grouping, MatrixSearchGroupBy key);
# define MATRIX_TYPE_SEARCH_GROUPINGS matrix_search_groupings_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixSearchGroupings, matrix_search_groupings, MATRIX, SEARCH_GROUPINGS, MatrixJsonCompact);
struct _MatrixSearchGroupingsClass {
MatrixJsonCompactClass parent_class;
};
MatrixSearchGroupings *matrix_search_groupings_new(void);
MatrixSearchGroupings *matrix_search_groupings_construct(GType object_type);
MatrixSearchGrouping **matrix_search_groupings_get_group_by(MatrixSearchGroupings *search_groupings, int *n_group_by);
void matrix_search_groupings_set_group_by(MatrixSearchGroupings *search_groupings, MatrixSearchGrouping **group_by, int n_group_by);
# define MATRIX_TYPE_SEARCH_ROOM_EVENTS matrix_search_room_events_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixSearchRoomEvents, matrix_search_room_events, MATRIX, SEARCH_ROOM_EVENTS, MatrixJsonCompact);
struct _MatrixSearchRoomEventsClass {
MatrixJsonCompactClass parent_class;
};
MatrixSearchRoomEvents *matrix_search_room_events_new(void);
MatrixSearchRoomEvents *matrix_search_room_events_construct(GType object_type);
MatrixSearchOrder matrix_search_room_events_get_order_by(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_order_by(MatrixSearchRoomEvents *search_room_events, MatrixSearchOrder order_by);
MatrixSearchKey *matrix_search_room_events_get_keys(MatrixSearchRoomEvents *search_room_events, guint *n_keys);
void matrix_search_room_events_set_keys(MatrixSearchRoomEvents *search_room_events, MatrixSearchKey *keys, guint n_keys);
MatrixEventContext *matrix_search_room_events_get_event_context(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_event_context(MatrixSearchRoomEvents *search_room_events, MatrixEventContext *event_context);
gboolean matrix_search_room_events_get_include_state(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_include_state(MatrixSearchRoomEvents *search_room_events, gboolean include_state);
const gchar *matrix_search_room_events_get_filter_id(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_filter_id(MatrixSearchRoomEvents *search_room_events, const gchar *filter_id);
MatrixFilter *matrix_search_room_events_get_filter(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_filter(MatrixSearchRoomEvents *search_room_events, MatrixFilter *filter);
const gchar *matrix_search_room_events_get_search_term(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_search_term(MatrixSearchRoomEvents *search_room_events, const gchar *search_term);
MatrixSearchGroupings *matrix_search_room_events_get_groupings(MatrixSearchRoomEvents *search_room_events);
void matrix_search_room_events_set_groupings(MatrixSearchRoomEvents *search_room_events, MatrixSearchGroupings *groupings);
# define MATRIX_TYPE_SEARCH_CATEGORIES matrix_search_categories_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixSearchCategories, matrix_search_categories, MATRIX, SEARCH_CATEGORIES, MatrixJsonCompact);
struct _MatrixSearchCategoriesClass {
MatrixJsonCompactClass parent_class;
};
MatrixSearchCategories *matrix_search_categories_new(void);
MatrixSearchCategories *matrix_search_categories_construct(GType object_type);
MatrixSearchRoomEvents *matrix_search_categories_get_room_events(MatrixSearchCategories *search_categories);
void matrix_search_categories_set_room_events(MatrixSearchCategories *search_categories, MatrixSearchRoomEvents *room_events);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_COMPACTS_H__ */

View File

@@ -1,725 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
namespace Matrix {
/**
* Abstract parent class for classes that can be saved to JSON.
*/
public abstract class JsonCompact {
public abstract Json.Node?
get_json_node()
throws Matrix.Error;
public string
get_json_data(out size_t datalen)
throws Matrix.Error
{
var generator = new Json.Generator();
generator.set_root(get_json_node());
return generator.to_data(out datalen);
}
}
/**
* Class to hold a filter.
*/
public class Filter : JsonCompact {
/**
* The event fields to include in the filtered events.
*/
public string[] event_fields { get; set; }
/**
* The desired event format for the filtered events (e.g. for
* matrix_api_sync())
*/
public EventFormat event_format {
get; set;
default = Matrix.EventFormat.CLIENT;
}
/**
* A filtering ruleset for presence events.
*/
public FilterRules? presence_filter { get; set; default = null; }
/**
* A filtering ruleset for room events.
*/
public RoomFilter? room_filter { get; set; default = null; }
/**
* Get the filter as a JSON node.
*/
public override Json.Node?
get_json_node()
throws Matrix.Error
{
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("event_fields");
builder.begin_array();
foreach (var entry in event_fields) {
builder.add_string_value(entry);
}
builder.end_array();
builder.set_member_name("event_format");
builder.add_string_value(
_g_enum_value_to_nick(typeof(EventFormat), event_format));
builder.set_member_name("presence");
builder.add_value(presence_filter.get_json_node());
builder.set_member_name("room");
builder.add_value(room_filter.get_json_node());
builder.end_object();
return builder.get_root();
}
}
/**
* Class to hold room filters.
*/
public class RoomFilter : JsonCompact {
/**
* If {{{true}}}, events for rooms that the user has left will
* be included in the filtered event list.
*/
public bool include_leave { get; set; default=true; }
/**
* Filtering rules for ephemeral events, i.e. events that are
* not recorded in the room history (typing notifications,
* receipts, etc.)
*/
public FilterRules? ephemeral { get; set; default = null; }
/**
* Filtering rules for state events.
*/
public FilterRules? state { get; set; default = null; }
/**
* Filtering rules for timeline events.
*/
public FilterRules? timeline { get; set; default = null; }
/**
* Get the room filters as a JSON node.
*/
public override Json.Node?
get_json_node()
throws Matrix.Error
{
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("include_leave");
builder.add_boolean_value(include_leave);
if (ephemeral != null) {
builder.set_member_name("ephemeral");
builder.add_value(ephemeral.get_json_node());
}
if (state != null) {
builder.set_member_name("state");
builder.add_value(state.get_json_node());
}
if (timeline != null) {
builder.set_member_name("timeline");
builder.add_value(timeline.get_json_node());
}
builder.end_object();
return builder.get_root();
}
}
/**
* Class to hold filtering rules.
*/
public class FilterRules : JsonCompact {
/**
* The limit of the count of returned events.
*/
public uint limit { get; set; }
/**
* List of message types to include in the filtered result.
*/
public string[] types { get; set; }
/**
* List of message types to exclude from the filtered
* result. A matching type will be excluded from the result
* even if it is listed in the types to include.
*/
public string[] excluded_types { get; set; }
/**
* List of senders to include in the filtered results.
*/
public string[] senders { get; set; }
/**
* List of senders to exclude from the filtered result. A
* matching sender will be excluded from the result even if it
* is listed in the senders to include.
*/
public string[] excluded_senders { get; set; }
/**
* List of rooms to include in the filtered results.
*/
public string[] rooms { get; set; }
/**
* List of rooms to exclude from the filtered result. A
* matching room will be excluded from the result even if it
* is listed in the rooms to include.
*/
public string[] excluded_rooms { get; set; }
/**
* Get the filtering rules as a JSON node.
*/
public override Json.Node?
get_json_node()
throws Matrix.Error
{
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("limit");
builder.add_int_value(limit);
if (rooms != null) {
builder.set_member_name("rooms");
builder.begin_array();
foreach (var entry in rooms) {
builder.add_string_value(entry);
}
builder.end_array();
}
if (excluded_rooms != null) {
builder.set_member_name("not_rooms");
builder.begin_array();
foreach (var entry in excluded_rooms) {
builder.add_string_value(entry);
}
builder.end_array();
}
if (senders != null) {
builder.set_member_name("senders");
builder.begin_array();
foreach (var entry in senders) {
builder.add_string_value(entry);
}
builder.end_array();
}
if (excluded_senders != null) {
builder.set_member_name("not_senders");
builder.begin_array();
foreach (var entry in excluded_senders) {
builder.add_string_value(entry);
}
builder.end_array();
}
if (types != null) {
builder.set_member_name("types");
builder.begin_array();
foreach (var entry in types) {
builder.add_string_value(entry);
}
builder.end_array();
}
if (excluded_types != null) {
builder.set_member_name("not_types");
builder.begin_array();
foreach(var entry in types) {
builder.add_string_value(entry);
}
builder.end_array();
}
builder.end_object();
return builder.get_root();
}
}
/**
* Class to hold 3rd party credential related data.
*/
public class @3PidCredential : JsonCompact {
/**
* The Identity Server used for this credential.
*/
public string? id_server { get; set; default = null; }
/**
* The session identifier got from the Identity Server.
*/
public string? session_id { get; set; default = null; }
/**
* The client secret that was used in the session with the
* Identity Server.
*/
public string? client_secret { get; set; default = null; }
/**
* Get 3rd party credential related data as a JSON node.
*/
public override Json.Node?
get_json_node()
throws Matrix.Error
{
if ((id_server == null)
|| (session_id == null)
|| (client_secret == null))
{
throw new Matrix.Error.INCOMPLETE(
"All fields of a 3PID credential must be filled!");
}
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("id_server");
builder.add_string_value(id_server);
builder.set_member_name("session_id");
builder.add_string_value(session_id);
builder.set_member_name("client_secret");
builder.add_string_value(client_secret);
builder.end_object();
return builder.get_root();
}
}
/**
* Class to hold pusher related data.
*/
public class Pusher : JsonCompact {
/**
* A device display name.
*/
public string? device_display_name { get; set; default = null; }
/**
* An application display name.
*/
public string? app_display_name { get; set; default = null; }
/**
* An application ID.
*/
public string? app_id { get; set; default = null; }
/**
* If {{{true}}}, the homeserver should add another pusher
* with the given push key and app ID in addition to any
* others with different user IDs. Otherwise, the homeserver
* must remove any other pushers with the same App ID and
* pushkey for different users.
*/
public bool append { get; set; default = true; }
/**
* The kind of the pusher. {{{http}}} makes a pusher that
* sends HTTP pokes. {{{null}}} deletes the pusher.
*/
public string? kind { get; set; default = null; }
/**
* The preferred language for receiving notifications,
* e.g. {{{en}}} or {{{en-US}}}.
*/
public string? lang { get; set; default = null; }
/**
* A string that determines what set of device rules will be
* matched when evaluating push rules for this pusher. It is
* an arbitrary string. Multiple devices may use the same
* profile tag. It is advised that when an app's data is
* copied or restored to a different device, this value remain
* the same. Client apps should offer ways to change the
* profile tag, optionally copying rules from the old profile
* tag. Maximum length is 32 bytes. If the profile tag is
* longer than this, it will be truncated
*/
public string? profile_tag { get; set; default = null; }
/**
* A unique identifier for this pusher. The value you should
* use for this is the routing or destination address
* information for the notification, for example, the APNS
* token for APNS or the Registration ID for GCM. If your
* notification client has no such concept, use any unique
* identifier. Maximum length is 512 bytes. If pushkey is
* longer than this, it will be truncated
*/
public string? pushkey { get; set; default = null; }
/**
* a dictionary of information for the pusher implementation
* itself. For example, if kind is {{{http}}}, this should
* contain an {{{url}}} member, which is the URL to use to
* send notifications to. This function creates a deep copy of
* the data, so it can be freed after this call.
*/
public Json.Node? data { get; set; default = null; }
/**
* Get the pusher data as a JSON node.
*/
public override Json.Node?
get_json_node()
throws Matrix.Error
{
if ((device_display_name == null)
|| (app_display_name == null)
|| (app_id == null)
|| (data == null)
|| (kind == null)
|| (lang == null)
|| (profile_tag == null)
|| (pushkey == null)) {
throw new Matrix.Error.INCOMPLETE("Pusher data incomplete");
}
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("device_display_name");
builder.add_string_value(device_display_name);
builder.set_member_name("app_display_name");
builder.add_string_value(app_display_name);
builder.set_member_name("app_id");
builder.add_string_value(app_id);
builder.set_member_name("append");
builder.add_boolean_value(append);
builder.set_member_name("kind");
builder.add_string_value(kind);
builder.set_member_name("lang");
builder.add_string_value(lang);
builder.set_member_name("profile_tag");
builder.add_string_value(profile_tag);
builder.set_member_name("pushkey");
builder.add_string_value(pushkey);
builder.set_member_name("data");
builder.add_value(data);
builder.end_object();
return builder.get_root();
}
}
public class EventContext : JsonCompact {
public int before_limit { get; set; default = -1; }
public int after_limit { get; set; default = -1; }
public bool include_profile { get; set; default = false; }
public override Json.Node?
get_json_node()
throws Matrix.Error
{
var builder = new Json.Builder();
builder.begin_object();
if (before_limit >= 0) {
builder.set_member_name("before_limit");
builder.add_int_value(before_limit);
}
if (after_limit >= 0) {
builder.set_member_name("after_limit");
builder.add_int_value(after_limit);
}
builder.set_member_name("include_profile");
builder.add_boolean_value(include_profile);
builder.end_object();
return builder.get_root();
}
}
public class SearchGrouping : JsonCompact {
public SearchGroupBy key { get; set; default = SearchGroupBy.NONE; }
public override Json.Node?
get_json_node()
throws Matrix.Error
{
if (key == SearchGroupBy.NONE) {
return null;
}
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("key");
builder.add_string_value(
_g_enum_value_to_nick(typeof(SearchGroupBy), key, true));
builder.end_object();
return builder.get_root();
}
}
public class SearchGroupings : JsonCompact {
public SearchGrouping[] group_by { get; set; }
public override Json.Node?
get_json_node()
throws Matrix.Error
{
if (group_by == null) {
return null;
}
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("group_by");
builder.begin_array();
int count = 0;
foreach (var entry in group_by) {
var node = entry.get_json_node();
if (node != null) {
count++;
builder.add_value(node);
}
}
if (count == 0) {
return null;
}
builder.end_array();
builder.end_object();
return builder.get_root();
}
}
public class SearchRoomEvents : JsonCompact {
public SearchOrder order_by { get; set; default = SearchOrder.RECENT; }
public SearchKey[] keys { get; set; }
public EventContext? event_context { get; set; default = null; }
public bool include_state { get; set; default = false; }
public string? filter_id { get; set; default = null; }
public Filter? filter { get; set; default = null; }
public string search_term { get; set; }
public SearchGroupings? groupings { get; set; default = null; }
public override Json.Node?
get_json_node()
throws Matrix.Error
{
Json.Node? node = null;
var builder = new Json.Builder();
if ((filter_id != null) && (filter != null)) {
throw new Matrix.Error.INCOMPLETE(
"filter and filter_id is exclusive to each other");
}
builder.begin_object();
builder.set_member_name("order_by");
builder.add_string_value(
_g_enum_value_to_nick(typeof(SearchOrder), order_by));
if (keys.length > 0) {
EnumClass key_class = (EnumClass)(typeof(SearchKey).class_ref());
var key_array = new Json.Array();
foreach (var entry in keys) {
unowned EnumValue? key_value = key_class.get_value(entry);
if (key_value != null) {
key_array.add_string_element(
key_value.value_nick.replace("-", "."));
}
}
if (key_array.get_length() > 0) {
node = new Json.Node(Json.NodeType.ARRAY);
node.set_array(key_array);
builder.set_member_name("keys");
builder.add_value(node);
}
}
if ((event_context != null)
&& ((node = event_context.get_json_node()) != null)) {
builder.set_member_name("event_context");
builder.add_value(node);
}
builder.set_member_name("include_state");
builder.add_boolean_value(include_state);
if ((filter != null)
&& ((node = filter.get_json_node()) != null)) {
builder.set_member_name("filter");
builder.add_value(node);
}
if (filter_id != null) {
builder.set_member_name("filter");
builder.add_string_value(filter_id);
}
builder.set_member_name("search_term");
builder.add_string_value(search_term);
if ((groupings != null)
&& ((node = groupings.get_json_node()) != null)) {
builder.set_member_name("groupings");
builder.add_value(node);
}
builder.end_object();
return builder.get_root();
}
}
public class SearchCategories : JsonCompact {
public SearchRoomEvents? room_events { get; set; default = null; }
public override Json.Node?
get_json_node()
throws Matrix.Error
{
Json.Node? node = null;
if ((room_events == null)
&& ((node = room_events.get_json_node()) != null)) {
return null;
}
var builder = new Json.Builder();
builder.begin_object();
builder.set_member_name("room_events");
builder.add_value(node);
builder.end_object();
return builder.get_root();
}
}
public Json.Node?
_json_node_deep_copy(Json.Node? node)
{
Json.Node ret;
if (node == null) {
return null;
}
ret = new Json.Node(node.get_node_type());
switch (node.get_node_type()) {
case Json.NodeType.OBJECT:
var new_obj = new Json.Object();
node.get_object().foreach_member(
(old_obj, member_name, member_node) => {
new_obj.set_member(
member_name,
_json_node_deep_copy(member_node));
});
ret.set_object(new_obj);
break;
case Json.NodeType.ARRAY:
var new_ary = new Json.Array();
node.get_array().foreach_element(
(old_ary, idx, element_node) => {
new_ary.add_element(
_json_node_deep_copy(element_node));
});
break;
case Json.NodeType.VALUE:
ret.set_value(node.get_value());
break;
case Json.NodeType.NULL:
break;
}
return ret;
}
}

596
src/matrix-event-base.c Normal file
View File

@@ -0,0 +1,596 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-base.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-base
* @short_description: abstract base class for Matrix events
* @title: Base class for events
*
* #MatrixEventBase is the abstract base class of Matrix events. All event classes in this
* library are derived from it, and custom classes should derived from it, too, if one wants to
* benefit from #MatrixClients (de)serialization capabilities.
*
* This class only defines the MatrixEventBase:event-type property, which is tied to the
* `event_type` field in a JSON representation. Subclasses should not get or set this property.
*
* Event objects can be created from JSON data (a #JsonNode) by calling
* matrix_event_base_new_from_json(), which will return the correct GObject type as long as
* it was registered with matrix_event_register_type().
*/
enum {
PROP_0,
PROP_EVENT_TYPE,
PROP_JSON,
NUM_PROPS
};
static GParamSpec* matrix_event_base_properties[NUM_PROPS];
static GHashTable *matrix_event_type_handlers = NULL;
typedef struct {
GError* _construct_error;
gboolean _inited;
JsonNode* _json;
gchar *_event_type;
} MatrixEventBasePrivate;
static void matrix_event_base_g_initable_interface_init (GInitableIface *iface);
/**
* MatrixEventBase:
*
* Abstract base class for event handlers.
*/
/**
* MatrixEventBaseClass:
* @from_json: function to initialize themselves from JSON data
* @to_json: function to export their data to JSON
*
* Class structure for #MatrixEventBase.
*/
G_DEFINE_TYPE_EXTENDED(MatrixEventBase, matrix_event_base, G_TYPE_OBJECT, G_TYPE_FLAG_ABSTRACT, G_ADD_PRIVATE (MatrixEventBase) G_IMPLEMENT_INTERFACE(G_TYPE_INITABLE, matrix_event_base_g_initable_interface_init));
static gboolean
matrix_event_base_initable_init(GInitable *g_initable, GCancellable *cancellable, GError **error)
{
MatrixEventBasePrivate *priv;
if (cancellable != NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNSUPPORTED,
"Cancellable initialization not supported");
return FALSE;
}
priv = matrix_event_base_get_instance_private(MATRIX_EVENT_BASE(g_initable));
if (priv->_construct_error != NULL) {
g_propagate_error(error, priv->_construct_error);
return FALSE;
}
priv->_inited = TRUE;
return TRUE;
}
static void
matrix_event_base_initialize_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
JsonObject *root;
JsonNode *node;
const gchar *json_event_type;
GError *inner_error = NULL;
g_return_if_fail(matrix_event_base != NULL);
if (json_node_get_node_type(json_data) != JSON_NODE_OBJECT) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INVALID_FORMAT,
"The event is not valid");
return;
}
root = json_node_get_object(json_data);
if ((node = json_object_get_member(root, "type")) == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Event type is not specified");
return;
}
json_event_type = json_node_get_string(node);
if ((priv->_event_type != NULL) && (g_strcmp0(priv->_event_type, json_event_type) != 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INVALID_TYPE,
"Changing event type is not supported");
return;
}
if ((node = json_object_get_member(root, "content")) == NULL) {
g_warning("content key is missing from an %s event", json_event_type);
// As event type objects depend on having this node, lets add it now.
JsonNode *content_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(content_node, json_object_new());
json_object_set_member(root, "content", content_node);
}
matrix_event_base_from_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return;
}
g_free(priv->_event_type);
priv->_event_type = g_strdup(json_event_type);
}
static void
matrix_event_base_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
JsonObject *root;
JsonNode *node;
g_return_if_fail(matrix_event_base != NULL);
root = json_node_get_object(json_data);
if ((node = json_object_get_member(root, "type")) != NULL) {
g_free(priv->_event_type);
priv->_event_type = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning("type is not present in an event");
}
}
/**
* matrix_event_base_from_json:
* @event: a #MatrixEventBase (or derived) object
* @json_data: a #JsonNode to load data from. It must hold a #JsonObject
* @error: a #GError, or %NULL to ignore errors
*
* Load data from a JSON object to the fields of @event.
*/
void
matrix_event_base_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
g_return_if_fail(matrix_event_base != NULL);
g_return_if_fail(json_data != NULL);
g_return_if_fail(json_node_get_node_type(json_data) != JSON_NODE_OBJECT);
MATRIX_EVENT_BASE_GET_CLASS(matrix_event_base)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_base_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
JsonObject *root;
g_return_if_fail(matrix_event_base != NULL);
root = json_node_get_object(json_data);
if (priv->_event_type == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate an event without type");
return;
}
json_object_set_string_member(root, "type", priv->_event_type);
}
/**
* matrix_event_base_to_json:
* @event: a #MatrixEventBase (or derived) object
* @json_data: a #JsonNode initialised to hold a #JsonObject
* @error: a #GError, or %NULL to ignore errors
*
* Export event data to a JSON object.
*/
void
matrix_event_base_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
g_return_if_fail(matrix_event_base != NULL);
g_return_if_fail(json_data != NULL);
g_return_if_fail(json_node_get_node_type(json_data) != JSON_NODE_OBJECT);
MATRIX_EVENT_BASE_GET_CLASS(matrix_event_base)->to_json(matrix_event_base, json_data, error);
}
/**
* matrix_event_base_new_from_json:
* @event_type: (nullable) (transfer none): an event type
* @json_data: (not nullable) (transfer none): a #JsonNode, holding a #JsonObject
* @error: (nullable): a #GError, or %NULL to ignore errors
*
* Create a new #MatrixEventBase derived object based on @event_type. If @event_type is %NULL,
* the event type is taken directly from the JSON data, namely the `"event_type"` field.
*
* After figuring out the event type (either from @event_type or from the event itself), this
* function calls matrix_event_get_handler() to get the handler #GType for this event. If
* none found, @error is set to #MATRIX_ERROR_INVALID_TYPE, and this function returns %NULL.
*
* The actual return type of this function is the same as the handling class (which is
* required to be a subclass of #MatrixEventBase).
*
* When object initialisation is done, matrix_event_base_from_json() is called to populate
* the event object.
*
* Returns: (transfer full): a new #MatrixEventBase devired object
*/
MatrixEventBase *
matrix_event_base_new_from_json(const gchar *event_type, JsonNode *json_data, GError **error)
{
GType event_gtype;
MatrixEventBase *ret = NULL;
GError *inner_error = NULL;
if (event_type == NULL) {
JsonNode *node;
if (json_data == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Either event_type or json_data must be set!");
return NULL;
}
if (json_node_get_node_type(json_data) != JSON_NODE_OBJECT) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INVALID_FORMAT,
"Event is not a JSON object!");
return NULL;
}
if ((node = json_object_get_member(json_node_get_object(json_data), "type")) == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"event_type is null and JSON object doesn't contain type!");
return NULL;
}
event_type = (gchar *)json_node_get_string(node);
}
if ((event_gtype = matrix_event_get_handler(event_type)) == G_TYPE_NONE) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INVALID_TYPE,
"No registered type for event type %s",
event_type);
return NULL;
}
ret = (MatrixEventBase *)g_object_new(event_gtype,
"event_type", event_type,
"json", json_data);
matrix_event_base_initable_init(G_INITABLE(ret), NULL, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return NULL;
}
return ret;
}
MatrixEventBase *
matrix_event_base_construct(GType object_type)
{
return (MatrixEventBase *)g_object_new(object_type, NULL);
}
/**
* matrix_event_base_get_event_type:
* @event: a #MatrixEventBase (or derived) object
*
* Get the event type of @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none): the event type
*/
const gchar *
matrix_event_base_get_event_type(MatrixEventBase *matrix_event_base)
{
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
g_return_val_if_fail(matrix_event_base != NULL, NULL);
return priv->_event_type;
}
static void
matrix_event_base_set_event_type(MatrixEventBase *matrix_event_base, const gchar *event_type)
{
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
g_return_if_fail(matrix_event_base != NULL);
g_free(priv->_event_type);
priv->_event_type = g_strdup (event_type);
g_object_notify_by_pspec((GObject *)matrix_event_base,
matrix_event_base_properties[PROP_EVENT_TYPE]);
}
JsonNode *
matrix_event_base_get_json(MatrixEventBase *matrix_event_base)
{
MatrixEventBasePrivate *priv;
JsonNode *result;
JsonNode *content_node;
JsonObject *root;
JsonObject *content_root;
GError *inner_error = NULL;
g_return_val_if_fail(matrix_event_base != NULL, NULL);
priv = matrix_event_base_get_instance_private(matrix_event_base);
result = json_node_new (JSON_NODE_OBJECT);
root = json_object_new();
json_node_set_object(priv->_json, root);
content_node = json_node_new(JSON_NODE_OBJECT);
content_root = json_object_new();
json_node_set_object(content_node, content_root);
json_object_set_member(root, "content", content_node);
matrix_event_base_to_json(matrix_event_base, priv->_json, &inner_error);
if (inner_error != NULL) {
g_error("Unable to generate JSON content: %s", inner_error->message);
g_error_free(inner_error);
g_object_unref(result);
return NULL;
}
json_node_unref(priv->_json);
priv->_json = result;
return priv->_json;
}
static void
matrix_event_base_set_json(MatrixEventBase *matrix_event_base, JsonNode *json)
{
GError* inner_error = NULL;
g_return_if_fail(matrix_event_base != NULL);
if (json != NULL) {
matrix_event_base_initialize_from_json(matrix_event_base, json, &inner_error);
if (inner_error != NULL) {
g_error("Unable to initialise from JSON data: %s", inner_error->message);
g_error_free(inner_error);
return;
}
}
g_object_notify_by_pspec((GObject *)matrix_event_base, matrix_event_base_properties[PROP_JSON]);
}
static void
matrix_event_base_get_property(GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec)
{
MatrixEventBase *matrix_event_base = MATRIX_EVENT_BASE(gobject);
switch (prop_id) {
case PROP_EVENT_TYPE:
g_value_set_string(value, matrix_event_base_get_event_type(matrix_event_base));
break;
case PROP_JSON:
g_value_set_boxed(value, matrix_event_base_get_json(matrix_event_base));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
}
}
static void
matrix_event_base_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventBase *matrix_event_base = MATRIX_EVENT_BASE(gobject);
switch (prop_id) {
case PROP_EVENT_TYPE:
matrix_event_base_set_event_type(matrix_event_base, g_value_get_string(value));
break;
case PROP_JSON:
matrix_event_base_set_json(matrix_event_base, g_value_get_boxed(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
}
}
static void
matrix_event_base_finalize(GObject *gobject)
{
MatrixEventBase *matrix_event_base = MATRIX_EVENT_BASE(gobject);
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
if (priv->_construct_error) {
g_error_free(priv->_construct_error);
}
priv->_json = (json_node_unref(priv->_json), NULL);
g_free(priv->_event_type);
G_OBJECT_CLASS(matrix_event_base_parent_class)->finalize(gobject);
}
static void
matrix_event_base_class_init(MatrixEventBaseClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_base_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_base_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_base_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_base_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_base_finalize;
/**
* MatrixEventBase:event-type:
*
* The type of the event. It should be namespaced similar to the Java package naming
* conventions, e.g. `com.example.subdomain.event.type`. It cannot be changed after object
* initialization.
*/
matrix_event_base_properties[PROP_EVENT_TYPE] = g_param_spec_string(
"event-type", "event-type", "event-type",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property(G_OBJECT_CLASS(klass),
PROP_EVENT_TYPE,
matrix_event_base_properties[PROP_EVENT_TYPE]);
/**
* MatrixEventBase:json:
*
* The event as a JSON node.
*/
matrix_event_base_properties[PROP_JSON] = g_param_spec_boxed(
"json", "json", "json",
JSON_TYPE_NODE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
g_object_class_install_property(G_OBJECT_CLASS(klass),
PROP_JSON,
matrix_event_base_properties[PROP_JSON]);
}
static void
matrix_event_base_g_initable_interface_init(GInitableIface *iface)
{
iface->init = matrix_event_base_initable_init;
}
static void
matrix_event_base_init(MatrixEventBase *matrix_event_base)
{
MatrixEventBasePrivate *priv = matrix_event_base_get_instance_private(matrix_event_base);
priv->_construct_error = NULL;
priv->_inited = FALSE;
priv->_event_type = NULL;
matrix_event_base_set_event_type(matrix_event_base, NULL);
}
/**
* matrix_event_get_handler:
* @event_type: (transfer none) (not nullable): the event type to look up
*
* Get the #GType of the class that is registered to handle events with type @event_type.
*
* Returns: a #GType, or #G_TYPE_NONE if no handler is registered
*/
GType
matrix_event_get_handler(const gchar *event_type)
{
GTypeClass *klass;
g_return_val_if_fail(event_type != NULL, G_TYPE_NONE);
if ((klass = (GTypeClass *)g_hash_table_lookup(matrix_event_type_handlers, event_type)) != NULL) {
return G_TYPE_FROM_CLASS(klass);
}
if (DEBUG) {
g_warning ("matrix-event-base.vala:243: No registered type for %s", event_type);
}
return G_TYPE_NONE;
}
/**
* matrix_event_register_type:
* @event_type: (transfer none): the type of the event
* @event_gtype: the #GType of the events handler
* @error: a #GError, or %NULL to ignore errors
*
* Registers @event_type to be handled by the type @event_gtype.
*/
void
matrix_event_register_type(const gchar *event_type, GType event_gtype, GError **error)
{
gchar *key;
GTypeClass *klass;
g_return_if_fail(event_type != NULL);
if (!g_type_is_a (event_gtype, MATRIX_EVENT_TYPE_BASE)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INVALID_TYPE,
"Invalid event type handler. It must be a subclass of MatrixEvent");
return;
}
if (matrix_event_type_handlers == NULL) {
matrix_event_type_handlers = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_type_class_unref);
}
key = g_strdup (event_type);
klass = g_type_class_ref (event_gtype);
g_hash_table_replace(matrix_event_type_handlers, key, klass);
}
/**
* matrix_event_unregister_type:
* @event_type: (transfer none): the event type to remove
*
* Unregister @param event_type.
*/
void
matrix_event_unregister_type(const gchar *event_type)
{
g_return_if_fail(event_type != NULL && matrix_event_type_handlers != NULL);
g_hash_table_remove (matrix_event_type_handlers, event_type);
}

59
src/matrix-event-base.h Normal file
View File

@@ -0,0 +1,59 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIX_SDK_EVENT_BASE_H__
# define __MATRIX_GLIX_SDK_EVENT_BASE_H__
# include <glib-object.h>
# include <json-glib/json-glib.h>
# define MATRIX_EVENT_TYPE_BASE (matrix_event_base_get_type ())
# define MATRIX_EVENT_BASE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_EVENT_TYPE_BASE, MatrixEventBase))
# define MATRIX_EVENT_BASE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), MATRIX_EVENT_TYPE_BASE, MatrixEventBaseClass))
# define MATRIX_EVENT_IS_BASE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_EVENT_TYPE_BASE))
# define MATRIX_EVENT_IS_BASE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), MATRIX_EVENT_TYPE_BASE))
# define MATRIX_EVENT_BASE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_EVENT_TYPE_BASE, MatrixEventBaseClass))
typedef struct _MatrixEventBase MatrixEventBase;
typedef struct _MatrixEventBaseClass MatrixEventBaseClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(MatrixEventBase, g_object_unref);
struct _MatrixEventBase {
GObject parent_instance;
};
struct _MatrixEventBaseClass {
GObjectClass parent_instance;
void (*from_json)(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error);
void (*to_json)(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error);
};
GType matrix_event_get_handler(const gchar *event_type);
void matrix_event_register_type(const gchar *event_type, GType event_gtype, GError **error);
void matrix_event_unregister_type(const gchar *event_type);
GType matrix_event_base_get_type(void) G_GNUC_CONST;
void matrix_event_base_from_json(MatrixEventBase *event, JsonNode *json_data, GError **error);
void matrix_event_base_to_json(MatrixEventBase *event, JsonNode *json_data, GError **error);
MatrixEventBase *matrix_event_base_new_from_json(const gchar *event_type, JsonNode *json_data, GError **error);
MatrixEventBase *matrix_event_base_construct(GType object_type);
const gchar *matrix_event_base_get_event_type(MatrixEventBase *event);
JsonNode *matrix_event_base_get_json(MatrixEventBase *event);
#endif /* __MATRIX_GLIX_SDK_EVENT_BASE_H__ */

View File

@@ -1,285 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Base class for Matrix events.
*/
public abstract class Matrix.Event.Base : GLib.Object, GLib.Initable {
private Error? _construct_error = null;
private bool _inited = false;
private Json.Node? _json;
protected string? _event_type = null;
/**
* The type of the event. It should be namespaced similar to the
* Java package naming conventions,
* e.g. `com.example.subdomain.event.type`. It cannot be changed
* after object initialization.
*/
public string? event_type {
get {
return _event_type;
}
construct {
_event_type = value;
}
default = null;
}
/**
* The event as a JSON node.
*/
public Json.Node? json {
get {
_json = new Json.Node(Json.NodeType.OBJECT);
_json.set_object(new Json.Object());
// Add the content node, as all event types must include it.
var content_root = new Json.Node(Json.NodeType.OBJECT);
var content_obj = new Json.Object();
content_root.set_object(content_obj);
_json.get_object().set_member("content", content_root);
try {
to_json(_json);
}
catch (Matrix.Error e) {
return null;
}
return _json;
}
construct {
if (value != null) {
try {
initialize_from_json(value);
} catch (Matrix.Error e) {}
}
}
}
public bool
init(GLib.Cancellable? cancellable = null)
throws Error, Matrix.Error
{
if (cancellable != null) {
throw new Matrix.Error.UNSUPPORTED(
"Cancellable initialization not supported");
}
if (_construct_error != null) {
throw _construct_error;
}
_inited = true;
return true;
}
private void
initialize_from_json(Json.Node json_data)
throws Matrix.Error
{
Json.Object root;
Json.Node node;
if (json_data.get_node_type() != Json.NodeType.OBJECT) {
throw new Matrix.Error.INVALID_FORMAT(
"The event is not valid");
}
root = json_data.get_object();
if ((node = root.get_member("type")) == null) {
throw new Matrix.Error.INCOMPLETE(
"Event type is not specified");
}
if ((_event_type != null)
&& (_event_type != node.get_string())) {
throw new Matrix.Error.INVALID_TYPE(
"Changing event type is not supported");
}
var evt_type = node.get_string();
if ((node = root.get_member("content")) == null) {
warning("content key is missing from the %s event", evt_type);
// As event type objects depend on having this node, lets
// add it now.
var content_node = new Json.Node(Json.NodeType.OBJECT);
content_node.set_object(new Json.Object());
root.set_member("content", content_node);
}
from_json(json_data);
_event_type = evt_type;
}
/**
* Subclasses should implement this function to initialize
* themselves from JSON data.
*/
public virtual void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
Json.Node? node;
if ((node = root.get_member("type")) != null) {
_event_type = node.get_string();
} else if (Config.DEBUG) {
warning("type is not present in an event");
}
}
/**
* Subclasses should implement this to export their data to JSON.
*/
public virtual void
to_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
if (_event_type == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate an event without type");
}
root.set_string_member("type", _event_type);
}
public static Base?
new_from_json(owned string? event_type = null,
Json.Node? json_data = null)
throws Matrix.Error, GLib.Error
{
GLib.Type? event_gtype;
Base? ret = null;
if (event_type == null) {
if (json_data == null) {
throw new Matrix.Error.INCOMPLETE(
"Either event_type or json_data must be set!");
}
if (json_data.get_node_type() != Json.NodeType.OBJECT) {
throw new Matrix.Error.INVALID_FORMAT(
"Event is not a JSON object!");
}
Json.Node? node;
if ((node = json_data.get_object().get_member("type")) == null) {
throw new Matrix.Error.INCOMPLETE(
"event_type is null and JSON object doesn't contain type!");
}
event_type = node.get_string();
}
if ((event_gtype = get_handler(event_type)) == null) {
throw new Matrix.Error.INVALID_TYPE(
"No registered type for event type %s",
event_type);
}
ret = (Base)Object.new(event_gtype,
event_type : event_type,
json : json_data);
ret.init();
return ret;
}
}
namespace Matrix.Event {
private HashTable<string, TypeClass>? type_handlers = null;
/**
* Get the {@link GLib.Type} of the class that is registered to
* handle events with type @param event_type.
*
* @param event_type the event type to look up
* @return a {@link GLib.Type} or {@link Matrix.Event} if no
* handler is registered
*/
public static GLib.Type?
get_handler(string event_type)
{
unowned GLib.TypeClass? klass = null;
if ((type_handlers != null)
&& ((klass = type_handlers.get(event_type)) != null)) {
return klass.get_type();
}
if (Config.DEBUG) {
warning("No registered type for %s", event_type);
}
return null;
}
/**
* Registers @param event_type to be handled by the
* type @param event_gtype.
*
* @param event_type the type of the event
* @param event_gtype the {@link GLib.Type} of the events handler
*/
public static void
register_type(string event_type, GLib.Type event_gtype)
throws Matrix.Error
{
if (!event_gtype.is_a(typeof(Matrix.Event.Base))) {
throw new Matrix.Error.INVALID_TYPE(
"Invalid event type handler. It must be a subclass of MatrixEvent");
}
if (type_handlers == null) {
type_handlers = new HashTable<string, GLib.TypeClass>(
str_hash, str_equal);
}
type_handlers.replace(event_type, event_gtype.class_ref());
}
/**
* Unregister @param event_type.
*
* @param event_type the event type to remove
*/
public static void
unregister_type(string event_type)
{
if (type_handlers != null) {
type_handlers.remove(event_type);
}
}
}

View File

@@ -0,0 +1,343 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-call-answer.h"
#include "utils.h"
#include "config.h"
/**
* SECTION:matrix-event-call-answer
* @short_description: event sent when a callee wishes to answer the call
*
* This event is sent by the callee when they wish to answer the call.
*/
enum {
PROP_0,
PROP_ANSWER_TYPE,
PROP_ANSWER_SDP,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_call_answer_properties[NUM_PROPERTIES];
typedef struct {
MatrixCallAnswerType _answer_type;
gchar* _answer_sdp;
} MatrixEventCallAnswerPrivate;
/**
* MatrixEventCallAnswer:
*
* Object structure.
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventCallAnswer, matrix_event_call_answer, MATRIX_EVENT_TYPE_CALL);
static void
matrix_event_call_answer_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallAnswerPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_answer_get_instance_private(MATRIX_EVENT_CALL_ANSWER(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "answer")) != NULL) {
JsonObject *answer_root = json_node_get_object(node);
if ((node = json_object_get_member(answer_root, "type")) != NULL) {
GError *inner_error = NULL;
MatrixCallAnswerType answer_type = _matrix_g_enum_nick_to_value(MATRIX_TYPE_CALL_ANSWER_TYPE, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
priv->_answer_type = MATRIX_CALL_ANSWER_TYPE_UNKNOWN;
#if DEBUG
g_warning("Unknown value %s for content.answer.type in a m.call.answer event", json_node_get_string(node));
#endif
} else {
priv->_answer_type = answer_type;
}
} else {
g_warning("content.answer.type is missing from a m.call.answer event");
}
if ((node = json_object_get_member(answer_root, "sdp")) != NULL) {
g_free(priv->_answer_sdp);
priv->_answer_sdp = g_strdup(json_node_get_string(node));
} else {
g_warning("content.answer.sdp is missing from a m.call.answer event");
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_call_answer_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_call_answer_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallAnswerPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonObject *answer_root;
JsonNode *content_node;
JsonNode *answer_node;
gchar *answer_type;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_answer_get_instance_private(MATRIX_EVENT_CALL_ANSWER(matrix_event_base));
if (priv->_answer_type == MATRIX_CALL_ANSWER_TYPE_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.answer event without a valid answer.type");
return;
}
if (priv->_answer_sdp == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.answer event without answer.sdp");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
answer_root = json_object_new();
answer_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(answer_node, answer_root);
answer_type = _matrix_g_enum_to_string(MATRIX_TYPE_CALL_ANSWER_TYPE, priv->_answer_type, '_');
json_object_set_string_member(answer_root, "type", answer_type);
g_free(answer_type);
json_object_set_string_member(answer_root, "sdp", priv->_answer_sdp);
json_object_set_member(content_root, "answer", answer_node);
MATRIX_EVENT_BASE_CLASS(matrix_event_call_answer_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventCallAnswer *
matrix_event_call_answer_construct(GType object_type)
{
return (MatrixEventCallAnswer *)matrix_event_call_construct(object_type);
}
/**
* matrix_event_call_answer_new:
*
* Create a new #MatrixEventCallAnswer object.
*
* Returns: (transfer full): a new #MatrixEventCallAnswer object
*/
MatrixEventCallAnswer *
matrix_event_call_answer_new(void)
{
return matrix_event_call_answer_construct(MATRIX_EVENT_TYPE_CALL_ANSWER);
}
/**
* matrix_event_call_answer_get_answer_type:
* @event: a #MatrixEventCallAnswer
*
* Get the answer type from @event.
*
* Returns: the answer type.
*/
MatrixCallAnswerType
matrix_event_call_answer_get_answer_type(MatrixEventCallAnswer *matrix_event_call_answer)
{
MatrixEventCallAnswerPrivate *priv;
g_return_val_if_fail(matrix_event_call_answer != NULL, 0);
priv = matrix_event_call_answer_get_instance_private(matrix_event_call_answer);
return priv->_answer_type;
}
/**
* matrix_event_call_answer_set_answer_type:
* @event: a #MatrixEventCallAnswer
* @answer_type: the answer type to set
*
* Set the answer type in @event.
*/
void
matrix_event_call_answer_set_answer_type(MatrixEventCallAnswer *matrix_event_call_answer, MatrixCallAnswerType answer_type)
{
MatrixEventCallAnswerPrivate *priv;
g_return_if_fail(matrix_event_call_answer != NULL);
priv = matrix_event_call_answer_get_instance_private(matrix_event_call_answer);
if (priv->_answer_type != answer_type) {
priv->_answer_type = answer_type;
g_object_notify_by_pspec((GObject *)matrix_event_call_answer, matrix_event_call_answer_properties[PROP_ANSWER_TYPE]);
}
}
/**
* matrix_event_call_answer_get_answer_sdp:
* @event: a #MatrixEventCallAnswer
*
* Get the answer SDP of @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the answer SDP
*/
const gchar *
matrix_event_call_answer_get_answer_sdp(MatrixEventCallAnswer *matrix_event_call_answer)
{
MatrixEventCallAnswerPrivate *priv;
g_return_val_if_fail(matrix_event_call_answer != NULL, NULL);
priv = matrix_event_call_answer_get_instance_private(matrix_event_call_answer);
return priv->_answer_sdp;
}
/**
* matrix_event_call_answer_set_answer_sdp:
* @event: a #MatrixEventCallAnswer
* @answer_sdp: (transfer none): an answew SDP
*
* Set the answer SDP in @event.
*/
void
matrix_event_call_answer_set_answer_sdp(MatrixEventCallAnswer *matrix_event_call_answer, const gchar *answer_sdp)
{
MatrixEventCallAnswerPrivate *priv;
g_return_if_fail(matrix_event_call_answer != NULL);
priv = matrix_event_call_answer_get_instance_private(matrix_event_call_answer);
if (g_strcmp0(answer_sdp, priv->_answer_sdp) != 0) {
g_free(priv->_answer_sdp);
priv->_answer_sdp = g_strdup(answer_sdp);
g_object_notify_by_pspec((GObject *)matrix_event_call_answer, matrix_event_call_answer_properties[PROP_ANSWER_SDP]);
}
}
static void
matrix_event_call_answer_finalize(GObject *gobject) {
MatrixEventCallAnswerPrivate *priv = matrix_event_call_answer_get_instance_private(MATRIX_EVENT_CALL_ANSWER(gobject));
g_free(priv->_answer_sdp);
G_OBJECT_CLASS(matrix_event_call_answer_parent_class)->finalize(gobject);
}
static void
matrix_event_call_answer_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventCallAnswer *matrix_event_call_answer = MATRIX_EVENT_CALL_ANSWER(gobject);
switch (property_id) {
case PROP_ANSWER_TYPE:
g_value_set_enum(value, matrix_event_call_answer_get_answer_type(matrix_event_call_answer));
break;
case PROP_ANSWER_SDP:
g_value_set_string(value, matrix_event_call_answer_get_answer_sdp(matrix_event_call_answer));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_answer_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventCallAnswer *matrix_event_call_answer = MATRIX_EVENT_CALL_ANSWER(gobject);
switch (property_id) {
case PROP_ANSWER_TYPE:
matrix_event_call_answer_set_answer_type(matrix_event_call_answer, g_value_get_enum(value));
break;
case PROP_ANSWER_SDP:
matrix_event_call_answer_set_answer_sdp(matrix_event_call_answer, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_answer_class_init(MatrixEventCallAnswerClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_call_answer_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_call_answer_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_call_answer_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_call_answer_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_call_answer_finalize;
/**
* MatrixEventCallAnswer:answer-type:
*
* The type of session description.
*/
matrix_event_call_answer_properties[PROP_ANSWER_TYPE] = g_param_spec_enum(
"answer-type", "answer-type", "answer-type",
MATRIX_TYPE_CALL_ANSWER_TYPE, MATRIX_CALL_ANSWER_TYPE_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ANSWER_TYPE, matrix_event_call_answer_properties[PROP_ANSWER_TYPE]);
/**
* MatrixEventCallAnswer:answer-sdp:
* The SDP text of the session description.
*/
matrix_event_call_answer_properties[PROP_ANSWER_SDP] = g_param_spec_string(
"answer-sdp", "answer-sdp", "answer-sdp",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ANSWER_SDP, matrix_event_call_answer_properties[PROP_ANSWER_SDP]);
}
static void
matrix_event_call_answer_init(MatrixEventCallAnswer *matrix_event_call_answer)
{
MatrixEventCallAnswerPrivate *priv = matrix_event_call_answer_get_instance_private(matrix_event_call_answer);
priv->_answer_type = MATRIX_CALL_ANSWER_TYPE_UNKNOWN;
priv->_answer_sdp = NULL;
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_CALL_ANSWER_H__
# define __MATRIX_GLIB_SDK_EVENT_CALL_ANSWER_H__
# include <glib-object.h>
# include "matrix-event-call-base.h"
# include "matrix-enumtypes.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_CALL_ANSWER (matrix_event_call_answer_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventCallAnswer, matrix_event_call_answer, MATRIX_EVENT, CALL_ANSWER, MatrixEventCall);
struct _MatrixEventCallAnswerClass {
MatrixEventCallClass parent_class;
};
MatrixEventCallAnswer* matrix_event_call_answer_new (void);
MatrixEventCallAnswer* matrix_event_call_answer_construct (GType object_type);
MatrixCallAnswerType matrix_event_call_answer_get_answer_type (MatrixEventCallAnswer *event);
void matrix_event_call_answer_set_answer_type (MatrixEventCallAnswer *event, MatrixCallAnswerType answer_type);
const gchar* matrix_event_call_answer_get_answer_sdp (MatrixEventCallAnswer *event);
void matrix_event_call_answer_set_answer_sdp (MatrixEventCallAnswer *event, const gchar *answer_sdp);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_CALL_ANSWER_H__ */

View File

@@ -1,102 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* This event is sent by the callee when they wish to answer the call.
*/
public class Matrix.Event.CallAnswer : Matrix.Event.Call {
/**
* The type of session description.
*/
public CallAnswerType answer_type { get; set; default = CallAnswerType.UNKNOWN; }
/**
* The SDP text of the session description.
*/
public string? answer_sdp { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("answer")) != null) {
var answer_root = node.get_object();
if ((node = answer_root.get_member("type")) != null) {
CallAnswerType? typ = (CallAnswerType?)_g_enum_nick_to_value(
typeof(CallAnswerType), node.get_string());
if (typ != null) {
_answer_type = typ;
} else {
_answer_type = CallAnswerType.UNKNOWN;
if (Config.DEBUG) {
warning("Unknown value %s for content.answer.type in a m.call.answer event",
node.get_string());
}
}
} else {
warning("content.answer.type is missing from a m.call.answer event");
}
if ((node = answer_root.get_member("sdp")) != null) {
_answer_sdp = node.get_string();
} else {
warning("content.answer.sdp is missing from a m.call.answer event");
}
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_answer_type == CallAnswerType.UNKNOWN) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.answer event without a valid answer.type");
}
if (_answer_sdp == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.answer event without answer.sdp");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
var answer_root = new Json.Object();
var answer_node = new Json.Node(Json.NodeType.OBJECT);
answer_node.set_object(answer_root);
answer_root.set_string_member("type",
_g_enum_value_to_nick(typeof(CallAnswerType),
_answer_type));
answer_root.set_string_member("sdp", _answer_sdp);
content_root.set_member("answer", answer_node);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,304 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-call-base.h"
#include "matrix-enumtypes.h"
/**
* SECTION:matrix-event-call-base
* @short_description: Abstract base class for call related events
*
* Base class for m.call.* events.
*/
enum {
PROP_0,
PROP_CALL_ID,
PROP_VERSION,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_call_properties[NUM_PROPERTIES];
typedef struct {
gchar *call_id;
gint _version;
} MatrixEventCallPrivate;
/**
* MatrixEventCall:
*
* Object structure.
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventCall, matrix_event_call, MATRIX_EVENT_TYPE_ROOM);
static void
matrix_event_call_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_get_instance_private(MATRIX_EVENT_CALL(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "call_id")) != NULL) {
g_free(priv->call_id);
priv->call_id = g_strdup(json_node_get_string(node));
} else {
g_warning("content.call_id is missing from a m.call.* event");
}
if ((node = json_object_get_member(content_root, "version")) != NULL) {
priv->_version = json_node_get_int(node);
} else {
g_warning("content.version is missing from a m.call.* event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_call_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_call_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_get_instance_private(MATRIX_EVENT_CALL(matrix_event_base));
if (priv->call_id == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.hangup event without call_id");
return;
}
if (priv->_version < 0) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.hangup event without version");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
json_object_set_string_member(content_root, "call_id", priv->call_id);
json_object_set_int_member(content_root, "version", priv->_version);
MATRIX_EVENT_BASE_CLASS(matrix_event_call_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventCall *
matrix_event_call_construct(GType object_type)
{
return (MatrixEventCall *)matrix_event_room_construct(object_type);
}
/**
* matrix_event_call_get_call_id:
* @event: a #MatrixEventCall
*
* Get the identifier of the call.
*
* The value returned is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the call ID
*/
const gchar *
matrix_event_call_get_call_id(MatrixEventCall *matrix_event_call)
{
MatrixEventCallPrivate *priv;
g_return_val_if_fail(matrix_event_call != NULL, NULL);
priv = matrix_event_call_get_instance_private(matrix_event_call);
return priv->call_id;
}
/**
* matrix_event_call_set_call_id:
* @event: a #MatrixEventCall
* @call_id: a call identifier
*
* Set the identifier of the call represented by @event.
*/
void
matrix_event_call_set_call_id(MatrixEventCall *matrix_event_call, const gchar *call_id)
{
MatrixEventCallPrivate *priv;
g_return_if_fail(matrix_event_call != NULL);
priv = matrix_event_call_get_instance_private(matrix_event_call);
if (g_strcmp0(call_id, priv->call_id) != 0) {
g_free(priv->call_id);
priv->call_id = g_strdup(call_id);
g_object_notify_by_pspec((GObject *)matrix_event_call, matrix_event_call_properties[PROP_CALL_ID]);
}
}
/**
* matrix_event_call_get_version:
* @event: a #MatrixEventCall
*
* Get the version of the call.
*
* Returns: the call version
*/
gint
matrix_event_call_get_version(MatrixEventCall *matrix_event_call)
{
MatrixEventCallPrivate *priv;
g_return_val_if_fail(matrix_event_call != NULL, 0);
priv = matrix_event_call_get_instance_private(matrix_event_call);
return priv->_version;
}
/**
* matrix_event_call_set_version:
* @event: a #MatrixEventCall
* @version: a call version
*
* Set the version of the call.
*/
void
matrix_event_call_set_version(MatrixEventCall *matrix_event_call, gint version)
{
MatrixEventCallPrivate *priv;
g_return_if_fail(matrix_event_call != NULL);
priv = matrix_event_call_get_instance_private(matrix_event_call);
if (priv->_version != version) {
priv->_version = version;
g_object_notify_by_pspec((GObject *)matrix_event_call, matrix_event_call_properties[PROP_VERSION]);
}
}
static void
matrix_event_call_finalize(GObject *gobject)
{
MatrixEventCallPrivate *priv = matrix_event_call_get_instance_private(MATRIX_EVENT_CALL(gobject));
g_free(priv->call_id);
G_OBJECT_CLASS(matrix_event_call_parent_class)->finalize(gobject);
}
static void
matrix_event_call_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventCall *matrix_event_call = MATRIX_EVENT_CALL(gobject);
switch (property_id) {
case PROP_CALL_ID:
g_value_set_string(value, matrix_event_call_get_call_id(matrix_event_call));
break;
case PROP_VERSION:
g_value_set_int(value, matrix_event_call_get_version(matrix_event_call));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventCall *matrix_event_call = MATRIX_EVENT_CALL(gobject);
switch (property_id) {
case PROP_CALL_ID:
matrix_event_call_set_call_id(matrix_event_call, g_value_get_string(value));
break;
case PROP_VERSION:
matrix_event_call_set_version(matrix_event_call, g_value_get_int(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_class_init(MatrixEventCallClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_call_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_call_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_call_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_call_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_call_finalize;
/**
* MatrixEventCall:call-id:
*
* The ID of the call this event relates to.
*/
matrix_event_call_properties[PROP_CALL_ID] = g_param_spec_string(
"call-id", "call-id", "call-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CALL_ID, matrix_event_call_properties[PROP_CALL_ID]);
/**
* MatrixEventCall:version:
*
* The version of the VoIP specification this message adheres to.
*/
matrix_event_call_properties[PROP_VERSION] = g_param_spec_int(
"version", "version", "version",
-1, G_MAXINT, -1,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_VERSION, matrix_event_call_properties[PROP_VERSION]);
}
static void
matrix_event_call_init(MatrixEventCall *matrix_event_call)
{
MatrixEventCallPrivate *priv = matrix_event_call_get_instance_private(matrix_event_call);
priv->call_id = NULL;
priv->_version = -1;
}

View File

@@ -0,0 +1,55 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_CALL_BASE_H__
# define __MATRIX_GLIB_SDK_EVENT_CALL_BASE_H__
# include <glib-object.h>
# include "matrix-event-room-base.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_CALL (matrix_event_call_get_type ())
# define MATRIX_EVENT_CALL(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_EVENT_TYPE_CALL, MatrixEventCall))
# define MATRIX_EVENT_CALL_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), MATRIX_EVENT_TYPE_CALL, MatrixEventCallClass))
# define MATRIX_EVENT_IS_CALL(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_EVENT_TYPE_CALL))
# define MATRIX_EVENT_IS_CALL_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), MATRIX_EVENT_TYPE_CALL))
# define MATRIX_EVENT_CALL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_EVENT_TYPE_CALL, MatrixEventCallClass))
typedef struct _MatrixEventCall MatrixEventCall;
typedef struct _MatrixEventCallClass MatrixEventCallClass;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(MatrixEventCall, g_object_unref);
struct _MatrixEventCall {
MatrixEventRoom parent_instance;
};
struct _MatrixEventCallClass {
MatrixEventRoomClass parent_class;
};
GType matrix_event_call_get_type (void) G_GNUC_CONST;
MatrixEventCall* matrix_event_call_construct (GType object_type);
const gchar *matrix_event_call_get_call_id (MatrixEventCall *event);
void matrix_event_call_set_call_id (MatrixEventCall *event, const gchar *call_id);
gint matrix_event_call_get_version (MatrixEventCall *event);
void matrix_event_call_set_version (MatrixEventCall *event, gint version);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_CALL_BASE_H__ */

View File

@@ -1,78 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Base class for m.call.* events.
*/
public abstract class Matrix.Event.Call : Matrix.Event.Room {
/**
* The ID of the call this event relates to.
*/
public string? call_id { get; set; default = null; }
/**
* The version of the VoIP specification this message adheres to.
*/
public int version { get; set; default = -1; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("call_id")) != null) {
_call_id = node.get_string();
} else {
warning("content.call_id is missing from a m.call.hangup event");
}
if ((node = content_root.get_member("version")) != null) {
_version = (int)node.get_int();
} else {
warning("content.version is missing from a m.call.hangup event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_call_id == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.hangup event without call_id");
}
if (_version < 0) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.hangup event without version");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
content_root.set_string_member("call_id", _call_id);
content_root.set_int_member("version", version);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,491 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-call-candidates.h"
#include "matrix-enumtypes.h"
/**
* SECTION:matrix-event-call-candidates
* @short_description: Event to represent call candidates
*
*/
struct _MatrixCallCandidate {
gchar *sdp_mid; /// The SDP media type this candidate is intended for.
int sdp_line_index; /// The index of the SDP 'm' line this candidate is intended for.
gchar *candidate; /// The SDP 'a' line of the candidate.
guint refcount;
};
/**
* MatrixCallCandidate:
*
* An opaque data structure to represent a call candidate.
*/
G_DEFINE_BOXED_TYPE(MatrixCallCandidate, matrix_call_candidate, (GBoxedCopyFunc)matrix_call_candidate_unref, (GBoxedFreeFunc)matrix_call_candidate_unref);
/**
* matrix_call_candidate_new:
*
* Create a new #MatrixCallCandidate object with a reference count of 1.
*
* Returns: (transfer full): a new #MatrixCallCandidate object
*/
MatrixCallCandidate *
matrix_call_candidate_new(void)
{
MatrixCallCandidate *ret;
ret = g_new0(MatrixCallCandidate, 1);
ret->refcount = 1;
return ret;
}
/**
* matrix_call_candidate_ref:
* @candidate: a #MatrixCallCandidate
*
* Increment reference count on @candidate.
*
* Returns: (transfer full): the same object
*/
MatrixCallCandidate *
matrix_call_candidate_ref(MatrixCallCandidate *matrix_call_candidate)
{
g_return_val_if_fail(matrix_call_candidate != NULL, NULL);
matrix_call_candidate->refcount++;
return matrix_call_candidate;
}
/**
* matrix_call_candidate_unref:
* @candidate: a #MatrixCallCandidate
*
* Decrement reference count on @candidate.
*
* If reference count reaches zero, @candidate gets freed.
*/
void
matrix_call_candidate_unref(MatrixCallCandidate *matrix_call_candidate)
{
g_return_if_fail(matrix_call_candidate != NULL);
g_free(matrix_call_candidate->sdp_mid);
g_free(matrix_call_candidate->candidate);
g_free(matrix_call_candidate);
}
/**
* matrix_call_candidate_get_sdp_mid:
* @candidate: a #MatrixCallCandidate
*
* Get the SDP mid of @candidate.
*
* Returns: (transfer none) (nullable): the SDP mid
*/
const gchar *
matrix_call_candidate_get_sdp_mid(MatrixCallCandidate *matrix_call_candidate)
{
g_return_val_if_fail(matrix_call_candidate != NULL, NULL);
return matrix_call_candidate->sdp_mid;
}
/**
* matrix_call_candidate_set_sdp_mid:
* @candidate: a #MatrixCallCandidate
* @sdp_mid: an SDP mid
*
* Set the SDP mid for @candidate.
*/
void
matrix_call_candidate_set_sdp_mid(MatrixCallCandidate *matrix_call_candidate, const gchar *sdp_mid)
{
g_return_if_fail(matrix_call_candidate);
g_free(matrix_call_candidate->sdp_mid);
matrix_call_candidate->sdp_mid = g_strdup(sdp_mid);
}
/**
* matrix_call_candidate_get_sdp_line_index:
* @candidate: a #MatrixCallCandidate
*
* Get the SDP line of @candidate.
*
* The value returned is owned by @candidate and should not be freed.
*
* Returns: (transfer none) (nullable): the SDP line
*/
int
matrix_call_candidate_get_sdp_line_index(MatrixCallCandidate *matrix_call_candidate)
{
g_return_val_if_fail(matrix_call_candidate != NULL, 0);
return matrix_call_candidate->sdp_line_index;
}
/**
* matrix_call_candidate_set_sdp_line_index:
* @candidate: a #MatrixCallCandidate
* @sdp_line_index: an SDP line index
*
* Set the SDP line index of @candidate.
*/
void
matrix_call_candidate_set_sdp_line_index(MatrixCallCandidate *matrix_call_candidate, int sdp_line_index)
{
g_return_if_fail(matrix_call_candidate != NULL);
matrix_call_candidate->sdp_line_index = sdp_line_index;
}
/**
* matrix_call_candidate_get_candidate:
* @candidate: a #MatrixCallCandidate
*
* Get the call candidate from @candidate.
*
* The returned value is owned by @candidate and should not be freed.
*
* Returns: (transfer none) (nullable): the candidate name
*/
const gchar *
matrix_call_candidate_get_candidate(MatrixCallCandidate *matrix_call_candidate)
{
g_return_val_if_fail(matrix_call_candidate != NULL, NULL);
return matrix_call_candidate->candidate;
}
/**
* matrix_call_candidate_set_candidate:
* @candidate: a #MatrixCallCandidate
* @candidate_name: (transfer none) (nullable): the name of the candidate
*
* Set the name of the call candidate.
*/
void
matrix_call_candidate_set_candidate(MatrixCallCandidate *matrix_call_candidate, const gchar *candidate)
{
g_return_if_fail(matrix_call_candidate != NULL);
g_free(matrix_call_candidate->candidate);
matrix_call_candidate->candidate = g_strdup(candidate);
}
enum {
PROP_0,
PROP_CANDIDATES,
NUM_PROPS
};
static GParamSpec *matrix_event_call_candidates_properties[NUM_PROPS];
typedef struct {
MatrixCallCandidate** _candidates;
gint _candidates_len;
} MatrixEventCallCandidatesPrivate;
/**
* MatrixEventCallCandidates:
*
* This event is sent by callers after sending an invite and by the callee after answering.
* Its purpose is to give the other party additional ICE candidates to try using to communicate.
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventCallCandidates, matrix_event_call_candidates, MATRIX_EVENT_TYPE_CALL);
static void
matrix_event_call_candidates_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallCandidatesPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_candidates_get_instance_private(MATRIX_EVENT_CALL_CANDIDATES(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "candidates")) != NULL) {
JsonArray *candidates = json_node_get_array(node);
gint len = json_array_get_length(candidates);
priv->_candidates = g_new(MatrixCallCandidate *, len);
for (gint i = 0; i < len; i++) {
JsonNode *cand_node = json_array_get_element(candidates, i);
JsonObject *cand_root = json_node_get_object(cand_node);
priv->_candidates[i] = matrix_call_candidate_new();
if ((node = json_object_get_member(cand_root, "sdpMid")) != NULL) {
priv->_candidates[i]->sdp_mid = g_strdup(json_node_get_string(node));
} else {
g_warning("sdpMid is missing from a candidate of a m.call.candidates event");
}
if ((node = json_object_get_member(cand_root, "sdpMLineIndex")) != NULL) {
priv->_candidates[i]->sdp_line_index = json_node_get_int(node);
} else {
g_warning("sdpMLineIndex is missing from a candidate of a m.call.candidates event");
}
if ((node = json_object_get_member(cand_root, "candidate")) != NULL) {
priv->_candidates[i]->candidate = g_strdup(json_node_get_string(node));
} else {
g_warning("candidate is missing from a candidate of a m.call.candidates event");
}
};
} else {
g_warning("content.candidates is missing from a m.call.candidates event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_call_candidates_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_call_candidates_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallCandidatesPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonArray *cands;
JsonNode *content_node;
JsonNode *cands_node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_candidates_get_instance_private(MATRIX_EVENT_CALL_CANDIDATES(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if (priv->_candidates_len < 1) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.candidates event without candidates");
return;
}
cands = json_array_new();
cands_node = json_node_new(JSON_NODE_ARRAY);
json_node_set_array(cands_node, cands);
json_object_set_member(content_root, "candidates", cands_node);
for (gint i = 0; i < priv->_candidates_len; i++) {
MatrixCallCandidate *entry = priv->_candidates[i];
JsonObject *cand_root;
JsonNode *cand_node;
if (entry->sdp_mid == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.candidates event with a missing sdpMid for candidates");
return;
}
if (entry->candidate == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.candidates event with a missing candidate for candidates");
return;
}
cand_root = json_object_new();
cand_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(cand_node, cand_root);
json_object_set_string_member(cand_root, "sdpMid", entry->sdp_mid);
json_object_set_int_member(cand_root, "sdpMLineIndex", entry->sdp_line_index);
json_object_set_string_member(cand_root, "candidate", entry->candidate);
json_array_add_element(cands, cand_node);
}
if (json_array_get_length(cands) < 1) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.candidates event with empty candidates list");
return;
}
MATRIX_EVENT_BASE_CLASS(matrix_event_call_candidates_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventCallCandidates *
matrix_event_call_candidates_construct(GType object_type)
{
return (MatrixEventCallCandidates *)matrix_event_call_construct(object_type);
}
/**
* matrix_event_call_candidates_new:
*
* Create a new #MatrixEventCallCandidates object.
*
* Returns: (transfer full): a new #MatrixEventCallCandidates object
*/
MatrixEventCallCandidates *
matrix_event_call_candidates_new(void)
{
return matrix_event_call_candidates_construct(MATRIX_EVENT_TYPE_CALL_CANDIDATES);
}
/**
* matrix_event_call_candidates_get_candidates:
* @event: a #MatrixEventCallCandidates:
* @n_candidates: (nullable): placeholder for the length of the list, or %NULL to ignore
*
* Get the list of the candidates from @event.
*
* The returned value is owned by @event, and should not be freed.
*
* Returns: (transfer none) (nullable): the list of candidates
*/
MatrixCallCandidate **
matrix_event_call_candidates_get_candidates(MatrixEventCallCandidates *matrix_event_call_candidates, int *n_candidates)
{
MatrixEventCallCandidatesPrivate *priv;
g_return_val_if_fail(matrix_event_call_candidates != NULL, NULL);
priv = matrix_event_call_candidates_get_instance_private(matrix_event_call_candidates);
if (n_candidates != NULL) {
*n_candidates = priv->_candidates_len;
}
return priv->_candidates;
}
/**
* matrix_event_call_candidates_set_candidates:
* @event: a #MatrixEventCallCandidates
* @candidates: a list of #MatrixCallCandidate objects
* @n_candidates: the number of elements in @candidates
*
* Set the list of call candidates in @event.
*/
void
matrix_event_call_candidates_set_candidates(MatrixEventCallCandidates *matrix_event_call_candidates, MatrixCallCandidate **candidates, int n_candidates)
{
MatrixEventCallCandidatesPrivate *priv;
g_return_if_fail(matrix_event_call_candidates != NULL);
priv = matrix_event_call_candidates_get_instance_private(matrix_event_call_candidates);
for (gint i = 0; i < priv->_candidates_len; i++) {
matrix_call_candidate_unref(priv->_candidates[i]);
}
g_free(priv->_candidates);
priv->_candidates = (MatrixCallCandidate **)g_new(MatrixCallCandidate, n_candidates);
priv->_candidates_len = n_candidates;
for (gint i = 0; i < n_candidates; i++) {
priv->_candidates[i] = matrix_call_candidate_ref(candidates[i]);
}
}
static void
matrix_event_call_candidates_finalize(GObject *gobject)
{
MatrixEventCallCandidatesPrivate *priv = matrix_event_call_candidates_get_instance_private(MATRIX_EVENT_CALL_CANDIDATES(gobject));
for (gint i = 0; i < priv->_candidates_len; i++) {
matrix_call_candidate_unref(priv->_candidates[i]);
}
g_free(priv->_candidates);
G_OBJECT_CLASS(matrix_event_call_candidates_parent_class)->finalize(gobject);
}
static void
matrix_event_call_candidates_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventCallCandidates *matrix_event_call_candidates = MATRIX_EVENT_CALL_CANDIDATES(gobject);
switch (property_id) {
case PROP_CANDIDATES:
g_value_set_boxed(value, matrix_event_call_candidates_get_candidates(matrix_event_call_candidates, NULL));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_candidates_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventCallCandidates *matrix_event_call_candidates = MATRIX_EVENT_CALL_CANDIDATES(gobject);
switch (property_id) {
case PROP_CANDIDATES:
{
gpointer boxed = g_value_get_boxed(value);
matrix_event_call_candidates_set_candidates(matrix_event_call_candidates, g_value_get_boxed(value), (boxed == NULL) ? 0 : g_strv_length(boxed));
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_candidates_class_init(MatrixEventCallCandidatesClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_call_candidates_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_call_candidates_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_call_candidates_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_call_candidates_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_call_candidates_finalize;
/**
* MatrixEventCallCandidates:candidates:
*
* The list of call candidates.
*/
matrix_event_call_candidates_properties[PROP_CANDIDATES] = g_param_spec_boxed(
"candidates", "candidates", "candidates",
MATRIX_TYPE_CALL_CANDIDATE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CANDIDATES, matrix_event_call_candidates_properties[PROP_CANDIDATES]);
}
static void
matrix_event_call_candidates_init(MatrixEventCallCandidates *matrix_event_call_candidates)
{
MatrixEventCallCandidatesPrivate *priv = matrix_event_call_candidates_get_instance_private(matrix_event_call_candidates);
priv->_candidates = NULL;
}

View File

@@ -0,0 +1,56 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_CALL_CANDIDATES_H__
# define __MATRIX_GLIB_SDK_EVENT_CALL_CANDIDATES_H__
# include <glib-object.h>
# include "matrix-event-call-base.h"
G_BEGIN_DECLS
# define MATRIX_TYPE_CALL_CANDIDATE matrix_call_candidate_get_type()
typedef struct _MatrixCallCandidate MatrixCallCandidate;
GType matrix_call_candidate_get_type(void) G_GNUC_CONST;
MatrixCallCandidate *matrix_call_candidate_new(void);
MatrixCallCandidate *matrix_call_candidate_ref(MatrixCallCandidate *candidate);
void matrix_call_candidate_unref(MatrixCallCandidate *candidate);
const gchar *matrix_call_candidate_get_sdp_mid(MatrixCallCandidate *candidate);
void matrix_call_candidate_set_sdp_mid(MatrixCallCandidate *candidate, const gchar *sdp_mid);
int matrix_call_candidate_get_sdp_line_index(MatrixCallCandidate *candidate);
void matrix_call_candidate_set_sdp_line_index(MatrixCallCandidate *candidate, int sdp_line_index);
const gchar *matrix_call_candidate_get_candidate(MatrixCallCandidate *candidate);
void matrix_call_candidate_set_candidate(MatrixCallCandidate *candidate, const gchar *candidate_name);
#define MATRIX_EVENT_TYPE_CALL_CANDIDATES (matrix_event_call_candidates_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventCallCandidates, matrix_event_call_candidates, MATRIX_EVENT, CALL_CANDIDATES, MatrixEventCall);
struct _MatrixEventCallCandidatesClass {
MatrixEventCallClass parent_class;
};
MatrixEventCallCandidates* matrix_event_call_candidates_new (void);
MatrixEventCallCandidates* matrix_event_call_candidates_construct (GType object_type);
MatrixCallCandidate* matrix_event_call_candidates_candidate_dup (const MatrixCallCandidate *event);
MatrixCallCandidate** matrix_event_call_candidates_get_candidates (MatrixEventCallCandidates *event, int *n_candidates);
void matrix_event_call_candidates_set_candidates (MatrixEventCallCandidates *event, MatrixCallCandidate **candidates, int n_candidates);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_CALL_CANDIDATES_H__ */

View File

@@ -1,132 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* This event is sent by callers after sending an invite and by the
* callee after answering. Its purpose is to give the other party
* additional ICE candidates to try using to communicate.
*/
public class Matrix.Event.CallCandidates : Matrix.Event.Call {
public struct Candidate {
string? sdp_mid; /// The SDP media type this candidate is
/// intended for.
int? sdp_line_index; /// The index of the SDP 'm' line this
/// candidate is intended for.
string? candidate; /// The SDP 'a' line of the candidate.
}
/**
* The list of candidates.
*/
public Candidate[] candidates { get; set; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("candidates")) != null) {
_candidates = new Candidate[node.get_array().get_length()];
node.get_array().foreach_element((ary, idx, cand_node) => {
var cand_root = cand_node.get_object();
var cand = Candidate();
if ((node = cand_root.get_member("sdpMid")) != null) {
cand.sdp_mid = node.get_string();
} else {
warning("sdpMid is missing from a candidate of a m.call.candidates event");
}
if ((node = cand_root.get_member("sdpMLineIndex")) != null) {
cand.sdp_line_index = (int)node.get_int();
} else {
warning("sdpMLineIndex is missing from a candidate of a m.call.candidates event");
}
if ((node = cand_root.get_member("candidate")) != null) {
cand.candidate = node.get_string();
} else {
warning("candidate is missing from a candidate of a m.call.candidates event");
}
_candidates[idx] = cand;
});
} else {
warning("content.candidates is missing from a m.call.candidates event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_candidates.length < 1) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.candidates event without candidates");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
var cands = new Json.Array();
foreach (var entry in _candidates) {
if (entry.sdp_mid == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.candidates event with a missing sdpMid for candidates");
}
if (entry.sdp_line_index == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.candidates event with a missing sdpMLineIndex for candidates");
}
if (entry.candidate == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.candidates event with a missing candidate for candidates");
}
var cand_obj = new Json.Object();
var cand_node = new Json.Node(Json.NodeType.OBJECT);
cand_node.set_object(cand_obj);
cand_obj.set_string_member("sdpMid", entry.sdp_mid);
cand_obj.set_int_member("sdpMLineIndex", entry.sdp_line_index);
cand_obj.set_string_member("candidate", entry.candidate);
cands.add_element(cand_node);
}
if (cands.get_length() < 1) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.candidates event with empty candidates list");
}
var cands_node = new Json.Node(Json.NodeType.ARRAY);
cands_node.set_array(cands);
content_root.set_member("candidates", cands_node);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,79 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-call-hangup.h"
/**
* SECTION:matrix-event-call-hangup
* @short_description: event to signal that a calling party has hung up the line
*
* This event is sent by either party to signal their termination of the call. This can be
* sent either once the call has has been established or before to abort the call.
*/
/**
* MatrixEventCallHangup:
*
*/
G_DEFINE_TYPE(MatrixEventCallHangup, matrix_event_call_hangup, MATRIX_EVENT_TYPE_CALL);
static void
matrix_event_call_hangup_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
g_return_if_fail(json_data != NULL);
MATRIX_EVENT_BASE_CLASS(matrix_event_call_hangup_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_call_hangup_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
g_return_if_fail(json_data != NULL);
MATRIX_EVENT_BASE_CLASS(matrix_event_call_hangup_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventCallHangup *
matrix_event_call_hangup_construct(GType object_type)
{
return (MatrixEventCallHangup *)matrix_event_call_construct(object_type);
}
/**
* matrix_event_call_hangup_new:
*
* Create a new #MatrixEventCallHangup object.
*
* Returns: (transfer full): a new #MatrixEventCallHangup object
*/
MatrixEventCallHangup *
matrix_event_call_hangup_new(void)
{
return matrix_event_call_hangup_construct(MATRIX_EVENT_TYPE_CALL_HANGUP);
}
static void
matrix_event_call_hangup_class_init(MatrixEventCallHangupClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_call_hangup_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_call_hangup_real_to_json;
}
static void
matrix_event_call_hangup_init(MatrixEventCallHangup *matrix_event_call_hangup)
{}

View File

@@ -16,27 +16,24 @@
* <http://www.gnu.org/licenses/>. * <http://www.gnu.org/licenses/>.
*/ */
/** #ifndef __MATRIX_GLIB_SDK_EVENT_CALL_HANGUP_H__
* The emote message type # define __MATRIX_GLIB_SDK_EVENT_CALL_HANGUP_H__
*
* This message is similar to `m.text` except that the sender is
* 'performing' the action contained in the `body` key, similar to
* `/me` in IRC. This message should be prefixed by the name of the
* sender. This message could also be represented in a different
* colour to distinguish it from regular `m.text` messages.
*/
public class Matrix.Message.Emote : Matrix.Message.Base {
public override void
from_json(Json.Node json_data)
throws Matrix.Error
{
base.from_json(json_data);
}
public override void # include <glib-object.h>
to_json(Json.Node json_data) # include "matrix-event-call-base.h"
throws Matrix.Error
{ G_BEGIN_DECLS
base.to_json(json_data);
} # define MATRIX_EVENT_TYPE_CALL_HANGUP matrix_event_call_hangup_get_type()
} G_DECLARE_DERIVABLE_TYPE(MatrixEventCallHangup, matrix_event_call_hangup, MATRIX_EVENT, CALL_HANGUP, MatrixEventCall);
struct _MatrixEventCallHangupClass {
MatrixEventCallClass parent_class;
};
MatrixEventCallHangup* matrix_event_call_hangup_new (void);
MatrixEventCallHangup* matrix_event_call_hangup_construct (GType object_type);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_CALL_HANGUP_H__ */

View File

@@ -0,0 +1,425 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-call-invite.h"
#include "utils.h"
#include "config.h"
/**
* SECTION:matrix-event-call-invite
* @short_description: event to signal a call request
*
* This event is sent by the caller when they wish to establish a call.
*/
enum {
PROP_0,
PROP_OFFER_TYPE,
PROP_SDP,
PROP_LIFETIME,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_call_invite_properties[NUM_PROPERTIES];
typedef struct {
MatrixCallOfferType _offer_type;
gchar* _sdp;
gint _lifetime;
} MatrixEventCallInvitePrivate;
/**
* MatrixEventCallInvite:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventCallInvite, matrix_event_call_invite, MATRIX_EVENT_TYPE_CALL);
static void
matrix_event_call_invite_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallInvitePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_call_invite_get_instance_private(MATRIX_EVENT_CALL_INVITE(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "offer")) != NULL) {
JsonObject *offer_root = json_node_get_object(node);
if ((node = json_object_get_member(offer_root, "type")) != NULL) {
GError *inner_error = NULL;
MatrixCallOfferType offer_type = _matrix_g_enum_nick_to_value(MATRIX_TYPE_CALL_OFFER_TYPE, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
priv->_offer_type = MATRIX_CALL_OFFER_TYPE_UNKNOWN;
#ifdef DEBUG
g_warning("Unknown value %s in content.offer.type of a m.call.invite event", json_node_get_string(node));
#endif
} else {
priv->_offer_type = offer_type;
}
} else {
g_warning("content.offer.type is missing from a m.call.invite event");
}
if ((node = json_object_get_member(offer_root, "sdp")) != NULL) {
g_free(priv->_sdp);
priv->_sdp = g_strdup(json_node_get_string(node));
} else {
g_warning("content.offer.sdp is missing from a m.call.invite event");
}
}
if ((node = json_object_get_member(content_root, "lifetime")) != NULL) {
priv->_lifetime = json_node_get_int(node);
} else {
g_warning("content.lifetime is missing from a m.call.invite event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_call_invite_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_call_invite_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventCallInvitePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonObject *offer_root;
JsonNode *content_node;
JsonNode *offer_node;
gchar *offer_type;
g_return_if_fail(json_data != NULL);
priv = matrix_event_call_invite_get_instance_private(MATRIX_EVENT_CALL_INVITE(matrix_event_base));
if (priv->_offer_type == MATRIX_CALL_OFFER_TYPE_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.invite without a valid offer.type");
return;
}
if (priv->_sdp == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.invite without offer.sdp");
return;
}
if (priv->_lifetime < 0) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.call.invite without lifetime");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
json_object_set_int_member(content_root, "lifetime", priv->_lifetime);
offer_root = json_object_new();
offer_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(offer_node, offer_root);
offer_type = _matrix_g_enum_to_string(MATRIX_TYPE_CALL_OFFER_TYPE, priv->_offer_type, '_');
json_object_set_string_member(offer_root, "type", offer_type);
g_free(offer_type);
json_object_set_string_member(offer_root, "sdp", priv->_sdp);
json_object_set_member(content_root, "offer", offer_node);
MATRIX_EVENT_BASE_CLASS(matrix_event_call_invite_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventCallInvite *
matrix_event_call_invite_construct(GType object_type)
{
return (MatrixEventCallInvite *)matrix_event_call_construct(object_type);
}
/**
* matrix_event_call_invite_new:
*
* Create a new #MatrixEventCallInvite object.
*
* Returns: (transfer full): a new #MatrixEventCallInvite object
*/
MatrixEventCallInvite *
matrix_event_call_invite_new(void) {
return matrix_event_call_invite_construct(MATRIX_EVENT_TYPE_CALL_INVITE);
}
/**
* matrix_event_call_invite_get_offer_type:
* @event: a #MatrixEventCallInvite
*
* Get the offer type of @event.
*
* Returns: the call offer type
*/
MatrixCallOfferType
matrix_event_call_invite_get_offer_type(MatrixEventCallInvite *matrix_event_call_invite)
{
MatrixEventCallInvitePrivate *priv;
g_return_val_if_fail(matrix_event_call_invite != NULL, 0);
priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
return priv->_offer_type;
}
/**
* matrix_event_call_invite_set_offer_type:
* @event: a #MatrixEventCallInvite
* @offer_type: the type of the call offer
*
* Set the offer type of the call in @event.
*/
void
matrix_event_call_invite_set_offer_type(MatrixEventCallInvite *matrix_event_call_invite, MatrixCallOfferType offer_type)
{
MatrixEventCallInvitePrivate *priv;
g_return_if_fail(matrix_event_call_invite != NULL);
priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
if (priv->_offer_type != offer_type) {
priv->_offer_type = offer_type;
g_object_notify_by_pspec((GObject *)matrix_event_call_invite, matrix_event_call_invite_properties[PROP_OFFER_TYPE]);
}
}
/**
* matrix_event_call_invite_get_sdp:
* @event: a #MatrixEventCallInvite
*
* Get the SDP line of the call.
*
* The returned value is owned by @event and should not by freed.
*.
* Returns: (transfer none): the SDP line of the call
*/
const gchar *
matrix_event_call_invite_get_sdp(MatrixEventCallInvite *matrix_event_call_invite)
{
MatrixEventCallInvitePrivate *priv;
g_return_val_if_fail(matrix_event_call_invite != NULL, NULL);
priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
return priv->_sdp;
}
/**
* matrix_event_call_invite_set_sdp:
* @event: a #MatrixEventCallInvite
* @sdp: an SDP line
*
* Set the SDP line ID of the call.
*/
void
matrix_event_call_invite_set_sdp(MatrixEventCallInvite *matrix_event_call_invite, const gchar *sdp)
{
MatrixEventCallInvitePrivate *priv;
g_return_if_fail(matrix_event_call_invite != NULL);
priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
if (g_strcmp0(sdp, priv->_sdp) != 0) {
g_free(priv->_sdp);
priv->_sdp = g_strdup(sdp);
g_object_notify_by_pspec((GObject *)matrix_event_call_invite, matrix_event_call_invite_properties[PROP_SDP]);
}
}
/**
* matrix_event_call_invite_get_lifetime:
* @event: a #MatrixEventCallInvite
*
* Get the lifetime of the call in @event.
*
* Returns: the lifetime, in milliseconds.
*/
gint
matrix_event_call_invite_get_lifetime(MatrixEventCallInvite *matrix_event_call_invite)
{
MatrixEventCallInvitePrivate *priv;
g_return_val_if_fail(matrix_event_call_invite != NULL, 0);
priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
return priv->_lifetime;
}
/**
* matrix_event_call_invite_set_lifetime:
* @event: a #MatrixEventCallInvite
* @lifetime: the lifetime of @event
*
* Set the lifetime of @event, in milliseconds.
*/
void
matrix_event_call_invite_set_lifetime(MatrixEventCallInvite *matrix_event_call_invite, gint lifetime)
{
MatrixEventCallInvitePrivate *priv;
g_return_if_fail(matrix_event_call_invite != NULL);
priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
if (priv->_lifetime != lifetime) {
priv->_lifetime = lifetime;
g_object_notify_by_pspec((GObject *)matrix_event_call_invite, matrix_event_call_invite_properties[PROP_LIFETIME]);
}
}
static void
matrix_event_call_invite_finalize(GObject *gobject)
{
MatrixEventCallInvitePrivate *priv = matrix_event_call_invite_get_instance_private(MATRIX_EVENT_CALL_INVITE(gobject));
g_free(priv->_sdp);
G_OBJECT_CLASS(matrix_event_call_invite_parent_class)->finalize(gobject);
}
static void
matrix_event_call_invite_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventCallInvite *matrix_event_call_invite = MATRIX_EVENT_CALL_INVITE(gobject);
switch (property_id) {
case PROP_OFFER_TYPE:
g_value_set_enum(value, matrix_event_call_invite_get_offer_type(matrix_event_call_invite));
break;
case PROP_SDP:
g_value_set_string(value, matrix_event_call_invite_get_sdp(matrix_event_call_invite));
break;
case PROP_LIFETIME:
g_value_set_int(value, matrix_event_call_invite_get_lifetime(matrix_event_call_invite));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_invite_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventCallInvite *matrix_event_call_invite = MATRIX_EVENT_CALL_INVITE(gobject);
switch (property_id) {
case PROP_OFFER_TYPE:
matrix_event_call_invite_set_offer_type(matrix_event_call_invite, g_value_get_enum(value));
break;
case PROP_SDP:
matrix_event_call_invite_set_sdp(matrix_event_call_invite, g_value_get_string(value));
break;
case PROP_LIFETIME:
matrix_event_call_invite_set_lifetime(matrix_event_call_invite, g_value_get_int(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_call_invite_class_init(MatrixEventCallInviteClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_call_invite_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_call_invite_real_to_json;
G_OBJECT_CLASS (klass)->get_property = matrix_event_call_invite_get_property;
G_OBJECT_CLASS (klass)->set_property = matrix_event_call_invite_set_property;
G_OBJECT_CLASS (klass)->finalize = matrix_event_call_invite_finalize;
/**
* MatrixEventCallInvite:offer-type:
*
* The type of session description.
*/
matrix_event_call_invite_properties[PROP_OFFER_TYPE] = g_param_spec_enum(
"offer-type", "offer-type", "offer-type",
MATRIX_TYPE_CALL_OFFER_TYPE, MATRIX_CALL_OFFER_TYPE_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_OFFER_TYPE, matrix_event_call_invite_properties[PROP_OFFER_TYPE]);
/**
* MatrixEventCallInvite:sdp:
*
* The SDP text of the session description.
*/
matrix_event_call_invite_properties[PROP_SDP] = g_param_spec_string(
"sdp", "sdp", "sdp",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_SDP, matrix_event_call_invite_properties[PROP_SDP]);
/**
* MatrixEventCallInvite:lifetime:
*
* The time in milliseconds that the invite is valid for. Once the invite age exceeds this
* value, clients should discard it. They should also no longer show the call as awaiting
* an answer in the UI.
*/
matrix_event_call_invite_properties[PROP_LIFETIME] = g_param_spec_int(
"lifetime", "lifetime", "lifetime",
G_MININT, G_MAXINT, -1,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_LIFETIME, matrix_event_call_invite_properties[PROP_LIFETIME]);
}
static void
matrix_event_call_invite_init(MatrixEventCallInvite *matrix_event_call_invite)
{
MatrixEventCallInvitePrivate *priv = matrix_event_call_invite_get_instance_private(matrix_event_call_invite);
priv->_offer_type = MATRIX_CALL_OFFER_TYPE_UNKNOWN;
priv->_sdp = NULL;
priv->_lifetime = -1;
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_CALL_INVITE_H__
# define __MATRIX_GLIB_SDK_EVENT_CALL_INVITE_H__
# include <glib-object.h>
# include "matrix-event-call-base.h"
# include "matrix-enumtypes.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_CALL_INVITE (matrix_event_call_invite_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventCallInvite, matrix_event_call_invite, MATRIX_EVENT, CALL_INVITE, MatrixEventCall);
struct _MatrixEventCallInviteClass {
MatrixEventCallClass parent_class;
};
MatrixEventCallInvite* matrix_event_call_invite_new (void);
MatrixEventCallInvite* matrix_event_call_invite_construct (GType object_type);
MatrixCallOfferType matrix_event_call_invite_get_offer_type (MatrixEventCallInvite *event);
void matrix_event_call_invite_set_offer_type (MatrixEventCallInvite *event, MatrixCallOfferType offer_type);
const gchar* matrix_event_call_invite_get_sdp (MatrixEventCallInvite *event);
void matrix_event_call_invite_set_sdp (MatrixEventCallInvite *event, const gchar* sdp);
gint matrix_event_call_invite_get_lifetime (MatrixEventCallInvite *event);
void matrix_event_call_invite_set_lifetime (MatrixEventCallInvite *event, gint lifetime);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_CALL_INVITE_H__ */

View File

@@ -1,124 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* This event is sent by the caller when they wish to establish a
* call.
*/
public class Matrix.Event.CallInvite : Matrix.Event.Call {
/**
* The type of session description.
*/
public CallOfferType offer_type { get; set; default = CallOfferType.UNKNOWN; }
/**
* The SDP text of the session description.
*/
public string? sdp { get; set; default = null; }
/**
* The time in milliseconds that the invite is valid for. Once the
* invite age exceeds this value, clients should discard it. They
* should also no longer show the call as awaiting an answer in
* the UI.
*/
public int lifetime { get; set; default = -1; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("offer")) != null) {
var offer_node = node.get_object();
if ((node = offer_node.get_member("type")) != null) {
CallOfferType? typ = (CallOfferType?)_g_enum_nick_to_value(
typeof(CallOfferType), node.get_string());
if (typ != null) {
_offer_type = typ;
} else {
_offer_type = CallOfferType.UNKNOWN;
if (Config.DEBUG) {
warning("Unknown value %s in content.offer.type of a m.call.invite event",
node.get_string());
}
}
} else {
warning("content.offer.type is missing from a m.call.invite event");
}
if ((node = offer_node.get_member("sdp")) != null) {
_sdp = node.get_string();
} else {
warning("content.offer.sdp is missing from a m.call.invite event");
}
}
if ((node = content_root.get_member("lifetime")) != null) {
_lifetime = (int)node.get_int();
} else {
warning("content.lifetime is missing from a m.call.invite event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_offer_type == CallOfferType.UNKNOWN) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.invite without a valid offer.type");
}
if (_sdp == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.invite without offer.sdp");
}
if (_lifetime < 0) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.call.invite without lifetime");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
content_root.set_int_member("lifetime", _lifetime);
var offer_root = new Json.Object();
var offer_node = new Json.Node(Json.NodeType.OBJECT);
offer_node.set_object(offer_root);
offer_root.set_string_member(
"type",
_g_enum_value_to_nick(typeof(CallOfferType),
_offer_type));
offer_root.set_string_member("sdp", _sdp);
content_root.set_member("offer", offer_node);
base.to_json(json_data);
}
}

580
src/matrix-event-presence.c Normal file
View File

@@ -0,0 +1,580 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-presence.h"
#include "matrix-event-room-base.h"
#include "matrix-enumtypes.h"
#include "config.h"
#include "utils.h"
/**
* SECTION:matrix-event-presence
* @short_description: event to inform the client of a userss presence change
*
* Informs the client of a user's presence state change.
*/
enum {
PROP_0,
PROP_AVATAR_URL,
PROP_DISPLAY_NAME,
PROP_LAST_ACTIVE_AGO,
PROP_USER_ID,
PROP_PRESENCE,
NUM_PROPS
};
static GParamSpec *matrix_event_presence_properties[NUM_PROPS];
typedef struct {
gchar *_avatar_url;
gchar *_display_name;
glong _last_active_ago;
gchar *_user_id;
gchar *_event_id;
MatrixPresence _presence;
} MatrixEventPresencePrivate;
/**
* MatrixEventPresence:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventPresence, matrix_event_presence, MATRIX_EVENT_TYPE_BASE);
static void
matrix_event_presence_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventPresencePrivate *priv;
JsonNode *content_node;
JsonNode *node;
JsonObject *root;
JsonObject *content_root;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_presence_get_instance_private(MATRIX_EVENT_PRESENCE(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(root, "event_id")) != NULL) {
g_free(priv->_event_id);
priv->_event_id = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning("event_id is missing from a m.presence event");
}
if ((node = json_object_get_member(content_root, "user_id")) != NULL) {
g_free(priv->_user_id);
priv->_user_id = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning("content.user_id is missing from the m.presence event");
// Workaround for having sender instead of content.user_id
// in most (room-dependent) presence events
if ((node = json_object_get_member(root, "sender")) != NULL) {
g_free(priv->_user_id);
priv->_user_id = g_strdup(json_node_get_string(node));
}
}
if ((node = json_object_get_member(content_root, "last_active_ago")) != NULL) {
priv->_last_active_ago = json_node_get_int(node);
}
if ((node = json_object_get_member(content_root, "avatar_url")) != NULL) {
g_free(priv->_avatar_url);
priv->_avatar_url = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(content_root, "displayname")) != NULL) {
g_free(priv->_display_name);
priv->_display_name = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(content_root, "presence")) != NULL) {
MatrixPresence presence;
presence = _matrix_g_enum_nick_to_value(MATRIX_TYPE_PRESENCE, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
g_clear_error(&inner_error);
priv->_presence = MATRIX_PRESENCE_UNKNOWN;
if (DEBUG) {
g_warning("Unknown value %s for content.presence in a m.presence event", json_node_get_string(node));
}
} else {
priv->_presence = presence;
}
} else if (DEBUG) {
g_warning("content.presence is missing from the m.presence event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_presence_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
if ((inner_error != NULL)) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_presence_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventPresencePrivate *priv;
JsonNode *content_node;
JsonObject *root;
JsonObject *content_root;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_presence_get_instance_private(MATRIX_EVENT_PRESENCE(matrix_event_base));
if (priv->_presence == MATRIX_PRESENCE_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNKNOWN_VALUE,
"Won't generate a m.presence event with an unkwnown presence");
return;
}
if (priv->_user_id == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.presence event without sender");
return;
}
if (priv->_event_id == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.presence event without event_id");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
json_object_set_string_member(root, "event_id", priv->_event_id);
json_object_set_string_member(content_root, "user_id", priv->_user_id);
json_object_set_string_member(content_root, "presence", _matrix_g_enum_to_string(MATRIX_TYPE_PRESENCE, priv->_presence, '_'));
if (priv->_last_active_ago >= 0) {
json_object_set_int_member(content_root, "last_active_ago", priv->_last_active_ago);
}
if (priv->_avatar_url != NULL) {
json_object_set_string_member(content_root, "avatar_url", priv->_avatar_url);
}
if (priv->_display_name != NULL) {
json_object_set_string_member(content_root, "displayname", priv->_display_name);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_presence_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
MatrixEventPresence *
matrix_event_presence_construct(GType object_type)
{
return (MatrixEventPresence *)matrix_event_base_construct(object_type);
}
/**
* matrix_event_presence_new:
*
* Create a new #MatrixEventPresence object.
*
* Returns: (transfer full): a new #MatrixEventPresence object
*/
MatrixEventPresence *
matrix_event_presence_new(void)
{
return matrix_event_presence_construct(MATRIX_EVENT_TYPE_PRESENCE);
}
/**
* matrix_event_presence_get_avatar_url:
* @event: a #MatrixEventPresence
*
* Get the URL of the users avatar in @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none): the avatar URL
*/
const gchar *
matrix_event_presence_get_avatar_url(MatrixEventPresence *matrix_event_presence)
{
MatrixEventPresencePrivate *priv;
g_return_val_if_fail(matrix_event_presence != NULL, NULL);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
return priv->_avatar_url;
}
/**
* matrix_event_presence_set_avatar_url:
* @event: a #MatrixEventPresence
* @avatar_url: (transfer none): an URL to the media of the users avatar
*
* Set the URL af the users avatar in @event.
*/
void
matrix_event_presence_set_avatar_url(MatrixEventPresence *matrix_event_presence, const gchar *avatar_url)
{
MatrixEventPresencePrivate *priv;
g_return_if_fail(matrix_event_presence != NULL);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
if (g_strcmp0(avatar_url, priv->_avatar_url) != 0) {
g_free(priv->_avatar_url);
priv->_avatar_url = g_strdup (avatar_url);
g_object_notify_by_pspec((GObject *)matrix_event_presence, matrix_event_presence_properties[PROP_AVATAR_URL]);
}
}
/**
* matrix_event_presence_get_display_name:
* @event: a #MatrixEventPresence
*
* Get the display name of the user in @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none): a display name
*/
const gchar *
matrix_event_presence_get_display_name(MatrixEventPresence *matrix_event_presence)
{
MatrixEventPresencePrivate *priv;
g_return_val_if_fail(matrix_event_presence != NULL, NULL);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
return priv->_display_name;
}
/**
* matrix_event_presence_set_display_name:
* @event: a #MatrixEventPresence
* @display_name: (transfer none): a display name
*
* Set the display name of the user in @event.
*/
void
matrix_event_presence_set_display_name (MatrixEventPresence *matrix_event_presence, const gchar *display_name)
{
MatrixEventPresencePrivate *priv;
g_return_if_fail(matrix_event_presence != NULL);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
if (g_strcmp0(display_name, priv->_display_name) != 0) {
g_free(priv->_display_name);
priv->_display_name = g_strdup(display_name);
g_object_notify_by_pspec((GObject *)matrix_event_presence, matrix_event_presence_properties[PROP_DISPLAY_NAME]);
}
}
/**
* matrix_event_presence_get_last_active_ago:
* @event: a #MatrixEventPresence
*
* Get the number of milliseconds since this user was last active.
*
* Returns: the number of milliseconds
*/
glong
matrix_event_presence_get_last_active_ago(MatrixEventPresence *matrix_event_presence)
{
MatrixEventPresencePrivate *priv;
g_return_val_if_fail(matrix_event_presence != NULL, -1);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
return priv->_last_active_ago;
}
/**
* matrix_event_presence_set_last_active_ago:
* @event: a #MatrixEventPresence
* @last_active_ago: the number of milliseconds since the user is inactive
*
* Set the number of milliseconds since the user in @event is inactive.
*/
void
matrix_event_presence_set_last_active_ago(MatrixEventPresence *matrix_event_presence, glong last_active_ago)
{
MatrixEventPresencePrivate *priv;
g_return_if_fail(matrix_event_presence != NULL);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
if (priv->_last_active_ago != last_active_ago) {
priv->_last_active_ago = last_active_ago;
g_object_notify_by_pspec((GObject *)matrix_event_presence, matrix_event_presence_properties[PROP_LAST_ACTIVE_AGO]);
}
}
/**
* matrix_event_presence_get_user_id:
* @event: a #MatrixEventPresence
*
* Get the user ID @event belongs to.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none): a user ID
*/
const gchar *
matrix_event_presence_get_user_id(MatrixEventPresence *event)
{
return matrix_event_room_get_sender(MATRIX_EVENT_ROOM(event));
}
/**
* matrix_event_presence_set_user_id:
* @event: a #MatrixEventPresence
* @user_id: (transfer none): the user ID @event should belong to
*
* Set the user ID in @event.
*/
void
matrix_event_presence_set_user_id(MatrixEventPresence *event, const gchar *user_id)
{
matrix_event_room_set_sender(MATRIX_EVENT_ROOM(event), user_id);
// TODO: Send this only if the property actually changed
g_object_notify_by_pspec((GObject *)event, matrix_event_presence_properties[PROP_USER_ID]);
}
/**
* matrix_event_presence_get_presence:
* @event: a #MatrixEventPresence
*
* Get the presence state of the user in @event.
*
* Returns: the presence state in @event
*/
MatrixPresence
matrix_event_presence_get_presence (MatrixEventPresence *matrix_event_presence) {
MatrixEventPresencePrivate *priv;
g_return_val_if_fail(matrix_event_presence != NULL, MATRIX_PRESENCE_UNKNOWN);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
return priv->_presence;
}
/**
* matrix_event_presence_set_presence:
* @event: a #MatrixEventPresence
* @presence: a #MatrixPresence value
*
* Set the presence state in @event.
*/
void
matrix_event_presence_set_presence(MatrixEventPresence *matrix_event_presence, MatrixPresence presence)
{
MatrixEventPresencePrivate *priv;
g_return_if_fail(matrix_event_presence != NULL);
priv = matrix_event_presence_get_instance_private(matrix_event_presence);
if (priv->_presence != presence) {
priv->_presence = presence;
g_object_notify_by_pspec((GObject *)matrix_event_presence, matrix_event_presence_properties[PROP_PRESENCE]);
}
}
static void
matrix_event_presence_get_property(GObject *gobject, guint property_id, GValue* value, GParamSpec* pspec)
{
MatrixEventPresencePrivate *priv = matrix_event_presence_get_instance_private(MATRIX_EVENT_PRESENCE(gobject));
switch (property_id) {
case PROP_AVATAR_URL:
g_value_set_string(value, priv->_avatar_url);
break;
case PROP_DISPLAY_NAME:
g_value_set_string(value, priv->_display_name);
break;
case PROP_LAST_ACTIVE_AGO:
g_value_set_long(value, priv->_last_active_ago);
break;
case PROP_USER_ID:
g_value_set_string(value, priv->_user_id);
break;
case PROP_PRESENCE:
g_value_set_enum(value, priv->_presence);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_presence_set_property(GObject *gobject, guint property_id, const GValue* value, GParamSpec* pspec)
{
MatrixEventPresence *matrix_event_presence = MATRIX_EVENT_PRESENCE(gobject);
switch (property_id) {
case PROP_AVATAR_URL:
matrix_event_presence_set_avatar_url(matrix_event_presence, g_value_get_string(value));
break;
case PROP_DISPLAY_NAME:
matrix_event_presence_set_display_name(matrix_event_presence, g_value_get_string(value));
break;
case PROP_LAST_ACTIVE_AGO:
matrix_event_presence_set_last_active_ago(matrix_event_presence, g_value_get_long(value));
break;
case PROP_USER_ID:
matrix_event_presence_set_user_id(matrix_event_presence, g_value_get_string(value));
break;
case PROP_PRESENCE:
matrix_event_presence_set_presence(matrix_event_presence, g_value_get_enum(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_presence_finalize(GObject *gobject)
{
MatrixEventPresencePrivate *priv = matrix_event_presence_get_instance_private(MATRIX_EVENT_PRESENCE(gobject));
g_free(priv->_avatar_url);
g_free(priv->_display_name);
g_free(priv->_user_id);
g_free(priv->_event_id);
G_OBJECT_CLASS(matrix_event_presence_parent_class)->finalize(gobject);
}
static void
matrix_event_presence_class_init(MatrixEventPresenceClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_presence_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_presence_real_to_json;
G_OBJECT_CLASS (klass)->get_property = matrix_event_presence_get_property;
G_OBJECT_CLASS (klass)->set_property = matrix_event_presence_set_property;
G_OBJECT_CLASS (klass)->finalize = matrix_event_presence_finalize;
/**
* MatrixEventPresence:avatar-url:
*
* The current avatar URL for this user, if any.
*/
matrix_event_presence_properties[PROP_AVATAR_URL] = g_param_spec_string(
"avatar-url", "avatar-url", "avatar-url",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AVATAR_URL, matrix_event_presence_properties[PROP_AVATAR_URL]);
/**
* MatrixEventPresence:display-name:
*
* The current display name for this user, if any.
*/
matrix_event_presence_properties[PROP_DISPLAY_NAME] = g_param_spec_string(
"display-name", "display-name", "display-name",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DISPLAY_NAME, matrix_event_presence_properties[PROP_DISPLAY_NAME]);
/**
* MatrixEventPresence:last-active-ago:
*
* The last time since this used performed some action, in milliseconds.
*
* This wont get into the generated event JSON if negative.
*/
matrix_event_presence_properties[PROP_LAST_ACTIVE_AGO] = g_param_spec_long(
"last-active-ago", "last-active-ago", "last-active-ago",
G_MINLONG, G_MAXLONG, -1,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_LAST_ACTIVE_AGO, matrix_event_presence_properties[PROP_LAST_ACTIVE_AGO]);
/**
* MatrixEventPresence:user-id:
*
* The user's ID.
*/
matrix_event_presence_properties[PROP_USER_ID] = g_param_spec_string(
"user-id", "user-id", "user-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_USER_ID, matrix_event_presence_properties[PROP_USER_ID]);
/**
* MatrixEventPresence:presence:
*
* The presence state for this user.
*/
matrix_event_presence_properties[PROP_PRESENCE] = g_param_spec_enum(
"presence", "presence", "presence",
MATRIX_TYPE_PRESENCE, MATRIX_PRESENCE_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_PRESENCE, matrix_event_presence_properties[PROP_PRESENCE]);
}
static void
matrix_event_presence_init(MatrixEventPresence *matrix_event_presence) {
MatrixEventPresencePrivate *priv = matrix_event_presence_get_instance_private(matrix_event_presence);
priv->_last_active_ago = -1;
priv->_user_id = NULL;
priv->_event_id = NULL;
priv->_presence = MATRIX_PRESENCE_UNKNOWN;
}

View File

@@ -0,0 +1,51 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_PRESENCE_H__
# define __MATRIX_GLIB_SDK_EVENT_PRESENCE_H__
# include <glib-object.h>
# include "matrix-event-base.h"
# include "matrix-types.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_PRESENCE matrix_event_presence_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventPresence, matrix_event_presence, MATRIX_EVENT, PRESENCE, MatrixEventBase);
struct _MatrixEventPresenceClass {
MatrixEventBaseClass parent_class;
};
GType matrix_event_presence_get_type (void) G_GNUC_CONST;
MatrixEventPresence* matrix_event_presence_new (void);
MatrixEventPresence* matrix_event_presence_construct (GType object_type);
const gchar* matrix_event_presence_get_avatar_url (MatrixEventPresence *event);
void matrix_event_presence_set_avatar_url (MatrixEventPresence *event, const gchar *avatar_url);
const gchar* matrix_event_presence_get_display_name (MatrixEventPresence *event);
void matrix_event_presence_set_display_name (MatrixEventPresence *event, const gchar *display_name);
glong matrix_event_presence_get_last_active_ago (MatrixEventPresence *event);
void matrix_event_presence_set_last_active_ago (MatrixEventPresence *event, glong last_active_ago);
const gchar* matrix_event_presence_get_user_id (MatrixEventPresence *event);
void matrix_event_presence_set_user_id (MatrixEventPresence *event, const gchar *user_id);
MatrixPresence matrix_event_presence_get_presence (MatrixEventPresence *event);
void matrix_event_presence_set_presence (MatrixEventPresence *event, MatrixPresence presence);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_PRESENCE_H__ */

View File

@@ -1,161 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class for representing presence events
*
* Informs the client of a user's presence state change.
*/
public class Matrix.Event.Presence : Matrix.Event.Base {
/**
* The current avatar URL for this user, if any.
*/
public string? avatar_url { get; set; }
/**
* The current display name for this user, if any.
*/
public string? display_name { get; set; }
/**
* The last time since this used performed some action, in
* milliseconds.
*
* This wont get into the generated event JSON if negative.
*/
public long last_active_ago { get; set; default = -1; }
/**
* The user's ID.
*/
public string? user_id { get; set; default = null; }
public string? event_id { get; set; default = null; }
/**
* The presence state for this user.
*/
public Matrix.Presence presence {
get; set;
default = Matrix.Presence.UNKNOWN;
}
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node;
if ((node = root.get_member("event_id")) != null) {
_event_id = node.get_string();
} else if (Config.DEBUG) {
warning("event_id is missing from a m.presence event");
}
if ((node = content_root.get_member("user_id")) != null) {
_user_id = node.get_string();
} else if (Config.DEBUG) {
warning("content.user_id is missing from the m.presence event");
// Workaround for having sender instead of content.user_id
// in most (room-dependent) presence events
if ((node = root.get_member("sender")) != null) {
_user_id = node.get_string();
}
}
if ((node = content_root.get_member("last_active_ago")) != null) {
_last_active_ago = (long)node.get_int();
}
if ((node = content_root.get_member("avatar_url")) != null) {
_avatar_url = node.get_string();
}
if ((node = content_root.get_member("displayname")) != null) {
_display_name = node.get_string();
}
if ((node = content_root.get_member("presence")) != null) {
Matrix.Presence? pres = (Matrix.Presence?)_g_enum_nick_to_value(
typeof(Matrix.Presence), node.get_string());
if (pres != null) {
_presence = pres;
} else {
_presence = Matrix.Presence.UNKNOWN;
if (Config.DEBUG) {
warning("Unknown value %s for content.presence in a m.presence event",
node.get_string());
}
}
} else if (Config.DEBUG) {
warning("content.presence is missing from the m.presence event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_presence == Matrix.Presence.UNKNOWN) {
throw new Matrix.Error.UNKNOWN_VALUE(
"Won't generate a m.presence event with an unkwnown presence");
}
if (_user_id == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.presence event without sender");
}
if (_event_id == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.presence event without event_id");
}
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
root.set_string_member("event_id", _event_id);
content_root.set_string_member("user_id", _user_id);
content_root.set_string_member("presence",
_g_enum_value_to_nick(typeof(Presence),
_presence));
if (last_active_ago >= 0) {
content_root.set_int_member("last_active_ago", last_active_ago);
}
if (avatar_url != null) {
content_root.set_string_member("avatar_url", avatar_url);
}
if (display_name != null) {
content_root.set_string_member("displayname", display_name);
}
base.to_json(json_data);
}
}

401
src/matrix-event-receipt.c Normal file
View File

@@ -0,0 +1,401 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-receipt.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-receipt
* @short_description: event to inform clients of new receipts
*
* This is the default event handler for `m.receipt` events.
*/
enum {
PROP_0,
PROP_ROOM_ID,
NUM_PROPS
};
static GParamSpec* matrix_event_receipt_properties[NUM_PROPS];
typedef struct {
gchar *_room_id;
GHashTable *_receipt_data;
} MatrixEventReceiptPrivate;
/**
* MatrixEventReceipt:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventReceipt, matrix_event_receipt, MATRIX_EVENT_TYPE_BASE);
typedef struct {
gchar *event_id;
gchar *typ;
gchar *user;
guint refcount;
} ReceiptData;
static gboolean
_rd_equal(ReceiptData *k1, ReceiptData *k2) {
if ((k1 == NULL) && (k2 == NULL)) {
return TRUE;
}
if ((k1 == NULL) || (k2 == NULL)) {
return FALSE;
}
return ((g_strcmp0(k1->event_id, k2->event_id) == 0) &&
(g_strcmp0(k1->typ, k2->typ) == 0) &&
(g_strcmp0(k1->user, k2->user) == 0));
}
static void
_rd_free(ReceiptData *receipt_data) {
g_return_if_fail(receipt_data != NULL);
if ( --receipt_data->refcount == 0) {
g_free(receipt_data->event_id);
g_free(receipt_data->typ);
g_free(receipt_data->user);
g_free(receipt_data);
}
}
static void
process_event(JsonObject *obj, const gchar *key, JsonNode *member_node, gpointer user_data)
{
JsonNode *node;
MatrixEventReceiptPrivate *priv = user_data;
if ((node = json_object_get_member(json_node_get_object(member_node), "m.read")) != NULL) {
JsonObject *read_obj = json_node_get_object(node);
JsonObjectIter inner_iter;
JsonNode *inner_node;
const gchar *inner_key;
json_object_iter_init(&inner_iter, read_obj);
while (json_object_iter_next(&inner_iter, &inner_key, &inner_node)) {
gulong *value;
ReceiptData *rd_key;
if (priv->_receipt_data == NULL) {
priv->_receipt_data = g_hash_table_new_full(g_direct_hash, (GEqualFunc)_rd_equal, (GDestroyNotify)_rd_free, g_free);
}
rd_key = g_new(ReceiptData, 1);
rd_key->event_id = g_strdup(key);
rd_key->typ = g_strdup("m.read");
rd_key->user = g_strdup(inner_key);
value = g_new(gulong, 1);
*value = json_node_get_int(json_object_get_member(json_node_get_object(inner_node), "ts"));
g_hash_table_replace(priv->_receipt_data, rd_key, value);
}
} else {
g_warning("content.$event-id.m.read is missing from a m.presence event");
}
}
static void
matrix_event_receipt_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventReceiptPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_receipt_get_instance_private(MATRIX_EVENT_RECEIPT(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(root, "room_id")) != NULL) {
g_free(priv->_room_id);
priv->_room_id = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning("room_id is missing from a m.receipt event");
}
json_object_foreach_member(content_root, process_event, priv);
MATRIX_EVENT_BASE_CLASS(matrix_event_receipt_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_receipt_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventReceiptPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
GHashTableIter iter;
gpointer gh_key;
gpointer gh_value;
gint i = 0;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_receipt_get_instance_private(MATRIX_EVENT_RECEIPT(matrix_event_base));
if (priv->_room_id == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.receipt without room_id");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
g_hash_table_iter_init(&iter, priv->_receipt_data);
while (g_hash_table_iter_next(&iter, &gh_key, &gh_value)) {
ReceiptData *key = gh_key;
gulong value = *(gulong *)gh_value;
JsonObject *event_object;
JsonObject *type_object;
JsonObject *user_object;
JsonNode *node;
if (key->event_id == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.receipt event with an empty event ID");
return;
}
if (key->typ == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.receipt event with an empty receipt type");
return;
}
if (key->user == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.receipt event with an empty user ID");
return;
}
i++;
if ((node = json_object_get_member(content_root, key->event_id)) == NULL) {
event_object = json_object_new();
node = json_node_new(JSON_TYPE_OBJECT);
json_node_set_object(node, event_object);
json_object_set_member(content_root, key->event_id, node);
} else {
event_object = json_node_get_object(node);
}
if ((node = json_object_get_member(event_object, key->typ)) == NULL) {
type_object = json_object_new();
node = json_node_new(JSON_TYPE_OBJECT);
json_node_set_object(node, type_object);
json_object_set_member(event_object, key->typ, node);
} else {
type_object = json_node_get_object(node);
}
if ((node = json_object_get_member(type_object, key->user)) == NULL) {
user_object = json_object_new();
node = json_node_new(JSON_TYPE_OBJECT);
json_node_set_object(node, user_object);
json_object_set_member(type_object, key->user, node);
} else {
user_object = json_node_get_object(node);
}
json_object_set_int_member(user_object, "ts", value);
}
if (i == 0) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.receipt event with no receipts");
return;
}
json_object_set_string_member(root, "room_id", priv->_room_id);
MATRIX_EVENT_BASE_CLASS(matrix_event_receipt_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
MatrixEventReceipt *
matrix_event_receipt_construct(GType object_type)
{
return (MatrixEventReceipt *)matrix_event_base_construct(object_type);
}
/**
* matrix_event_receipt_new:
*
* Create a new #MatrixEventReceipt object.
*
* Returns: (transfer full): a new #MatrixEventReceipt object
*/
MatrixEventReceipt *
matrix_event_receipt_new(void)
{
return matrix_event_receipt_construct(MATRIX_EVENT_TYPE_RECEIPT);
}
/**
* matrix_event_receipt_get_room_id:
* @event: a #MatrixEventReceipt
*
* Get the room ID @event belongs to.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a room ID
*/
const gchar *
matrix_event_receipt_get_room_id(MatrixEventReceipt *matrix_event_receipt)
{
MatrixEventReceiptPrivate *priv;
g_return_val_if_fail(matrix_event_receipt != NULL, NULL);
priv = matrix_event_receipt_get_instance_private(matrix_event_receipt);
return priv->_room_id;
}
/**
* matrix_event_receipt_set_room_id:
* @event: a #MatrixEventReceipt
* @room_id: (transfer none) (nullable): a room ID
*
* Set the room ID for @event.
*/
void
matrix_event_receipt_set_room_id(MatrixEventReceipt *matrix_event_receipt, const gchar *room_id)
{
MatrixEventReceiptPrivate *priv;
g_return_if_fail(matrix_event_receipt != NULL);
priv = matrix_event_receipt_get_instance_private(matrix_event_receipt);
if (g_strcmp0(room_id, priv->_room_id) != 0) {
g_free(priv->_room_id);
priv->_room_id = g_strdup(room_id);
g_object_notify_by_pspec((GObject *)matrix_event_receipt, matrix_event_receipt_properties[PROP_ROOM_ID]);
}
}
static void
matrix_event_receipt_finalize(GObject *gobject)
{
MatrixEventReceiptPrivate *priv = matrix_event_receipt_get_instance_private(MATRIX_EVENT_RECEIPT(gobject));
g_free(priv->_room_id);
g_hash_table_unref(priv->_receipt_data);
G_OBJECT_CLASS(matrix_event_receipt_parent_class)->finalize(gobject);
}
static void
matrix_event_receipt_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventReceipt *matrix_event_receipt = MATRIX_EVENT_RECEIPT(gobject);
switch (property_id) {
case PROP_ROOM_ID:
g_value_set_string(value, matrix_event_receipt_get_room_id(matrix_event_receipt));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_receipt_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventReceipt *matrix_event_receipt = MATRIX_EVENT_RECEIPT(gobject);
switch (property_id) {
case PROP_ROOM_ID:
matrix_event_receipt_set_room_id(matrix_event_receipt, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_receipt_class_init(MatrixEventReceiptClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_receipt_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_receipt_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_receipt_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_receipt_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_receipt_finalize;
/**
* MatrixEventReceipt:room-id:
*
* The room ID.
*/
matrix_event_receipt_properties[PROP_ROOM_ID] = g_param_spec_string(
"room-id", "room-id", "room-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ROOM_ID, matrix_event_receipt_properties[PROP_ROOM_ID]);
}
static void
matrix_event_receipt_init(MatrixEventReceipt *matrix_event_receipt)
{
MatrixEventReceiptPrivate *priv;
priv = matrix_event_receipt_get_instance_private(matrix_event_receipt);
priv->_room_id = NULL;
priv->_receipt_data = NULL;
}

View File

@@ -0,0 +1,42 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_RECEIPT_H__
# define __MATRIX_GLIB_SDK_EVENT_RECEIPT_H__
# include <glib-object.h>
# include "matrix-event-base.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_RECEIPT matrix_event_receipt_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventReceipt, matrix_event_receipt, MATRIX_EVENT, RECEIPT, MatrixEventBase);
struct _MatrixEventReceiptClass {
MatrixEventBaseClass parent_class;
};
GType matrix_event_receipt_get_type (void) G_GNUC_CONST;
MatrixEventReceipt* matrix_event_receipt_new (void);
MatrixEventReceipt* matrix_event_receipt_construct (GType object_type);
const gchar* matrix_event_receipt_get_room_id (MatrixEventReceipt *event);
void matrix_event_receipt_set_room_id (MatrixEventReceipt *event, const gchar *room_id);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_RECEIPT_H__ */

View File

@@ -1,171 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold m.receipt events.
*
* Informs the client of new receipts.
*/
public class Matrix.Event.Receipt : Matrix.Event.Base {
public string? room_id { get; set; default = null; }
private struct ReceiptData {
string event_id;
string typ;
string user;
}
private HashTable<ReceiptData?, ulong?> _receipt_data = null;
private static bool
_rd_equal(ReceiptData k1, ReceiptData k2)
{
return ((k1.event_id == k2.event_id)
&& (k1.typ == k2.typ)
&& (k1.user == k2.user));
}
private void
_init_receipt_data()
{
_receipt_data = new HashTable<ReceiptData?, ulong?>(null, (EqualFunc)_rd_equal);
}
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node;
if ((node = root.get_member("room_id")) != null) {
_room_id = node.get_string();
} else if (Config.DEBUG) {
warning("room_id is missing from a m.receipt event");
}
content_root.foreach_member((obj, event_id, event_content) => {
if ((node = event_content.get_object()
.get_member("m.read")) != null) {
var read_obj = node.get_object();
read_obj.foreach_member((robj, r_user_id, r_content) => {
if (_receipt_data == null) {
_init_receipt_data();
}
ReceiptData rd_key = ReceiptData() {
event_id = event_id,
typ = "m.read",
user = r_user_id
};
_receipt_data[rd_key] =
(ulong)r_content.get_object().get_member("ts").get_int();
});
} else {
warning("content.$event-id.m.read is missing from a m.presence event");
}
});
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
Json.Node? node = null;
if (_room_id == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.receipt without room_id");
}
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
int i = 0;
Matrix.Error? error = null;
_receipt_data.foreach(
(key, value) => {
Json.Object event_object;
Json.Object type_object;
Json.Object user_object;
if (key.event_id == null) {
error = new Matrix.Error.INCOMPLETE(
"Won't generate a m.receipt event with an empty event ID");
}
if (key.typ == null) {
error = new Matrix.Error.INCOMPLETE(
"Won't generate a m.receipt event with an empty receipt type");
}
if (key.user == null) {
error = new Matrix.Error.INCOMPLETE(
"Won't generate a m.receipt event with an empty user ID");
}
i++;
if ((node = content_root.get_member(key.event_id)) == null) {
event_object = new Json.Object();
node = new Json.Node(Json.NodeType.OBJECT);
node.set_object(event_object);
content_root.set_member(key.event_id, node);
} else {
event_object = node.get_object();
}
if ((node = event_object.get_member(key.typ)) == null) {
type_object = new Json.Object();
node = new Json.Node(Json.NodeType.OBJECT);
node.set_object(type_object);
event_object.set_member(key.typ, node);
} else {
type_object = node.get_object();
}
if ((node = type_object.get_member(key.user)) == null) {
user_object = new Json.Object();
node = new Json.Node(Json.NodeType.OBJECT);
node.set_object(user_object);
type_object.set_member(key.user, node);
} else {
user_object = node.get_object();
}
user_object.set_int_member("ts", value);
});
if (error != null) {
throw error;
}
if (i == 0) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.receipt event with no receipts");
}
root.set_string_member("room_id", _room_id);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,298 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-aliases.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-aliases
* @short_description: event to list the aliases of a room
*
* This is the default event handler for `m.room.aliases` events.
*
* This event is sent by a homeserver directly to inform of changes to the list of aliases it
* knows about for that room.
*
* The state_key for this event is set to the homeserver which owns the room alias.
*
* The entire set of known aliases for the room is the union of all the `m.room.aliases`
* events, one for each homeserver. Clients should check the validity of any room alias given
* in this list before presenting it to the user as trusted fact. The lists given by this
* event should be considered simply as advice on which aliases might exist, for which the
* client can perform the lookup to confirm whether it receives the correct room ID.
*/
enum {
PROP_0,
PROP_ALIASES,
NUM_PROPS
};
static GParamSpec* matrix_event_room_aliases_properties[NUM_PROPS];
typedef struct {
gchar** _aliases;
gint _aliases_len;
gint __aliases_size_;
} MatrixEventRoomAliasesPrivate;
/**
* MatrixEventRoomAliases:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomAliases, matrix_event_room_aliases, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_aliases_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomAliasesPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_aliases_get_instance_private(MATRIX_EVENT_ROOM_ALIASES(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "aliases")) != NULL) {
JsonArray *aliases;
gint n_aliases;
aliases = json_node_get_array(node);
n_aliases = json_array_get_length(aliases);
for (gint i = 0; i < priv->_aliases_len; i++) {
g_free(priv->_aliases[i]);
}
g_free(priv->_aliases);
priv->_aliases = g_new(gchar *, n_aliases);
for (gint i = 0; i < n_aliases; i++) {
JsonNode *element = json_array_get_element(aliases, i);
priv->_aliases[i] = g_strdup(json_node_get_string(element));
}
} else if (DEBUG) {
g_warning("content.aliases is missing from a m.room.aliases event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_aliases_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_room_aliases_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomAliasesPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonArray *aliases_ary;
JsonNode *content_node;
JsonNode *aliases_node;
GError *inner_error = NULL;
priv = matrix_event_room_aliases_get_instance_private(MATRIX_EVENT_ROOM_ALIASES(matrix_event_base));
if (priv->_aliases_len == 0) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.aliases event without aliases");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
aliases_ary = json_array_new();
for (gint i = 0; i < priv->_aliases_len; i++) {
json_array_add_string_element(aliases_ary, priv->_aliases[i]);
}
aliases_node = json_node_new(JSON_TYPE_ARRAY);
json_node_set_array(aliases_node, aliases_ary);
json_object_set_member(content_root, "aliases", aliases_node);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_aliases_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
MatrixEventRoomAliases *
matrix_event_room_aliases_construct (GType object_type)
{
return (MatrixEventRoomAliases *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_aliases_new:
*
* Create a new #MatrixEventRoomAliases object.
*
* Returns: (transfer full): a new #MatrixEventRoomAliases object
*/
MatrixEventRoomAliases *
matrix_event_room_aliases_new(void)
{
return matrix_event_room_aliases_construct(MATRIX_EVENT_TYPE_ROOM_ALIASES);
}
/**
* matrix_event_room_aliases_get_aliases:
* @event: a MatrixEventRoomAliases
* @n_aliases: placeholder for the length of the list, or %NULL to ignore
*
* Get the list of aliases from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the list of aliases
*/
const gchar **
matrix_event_room_aliases_get_aliases(MatrixEventRoomAliases *matrix_event_room_aliases, int *n_aliases)
{
MatrixEventRoomAliasesPrivate *priv;
g_return_val_if_fail(matrix_event_room_aliases != NULL, NULL);
priv = matrix_event_room_aliases_get_instance_private(matrix_event_room_aliases);
if (n_aliases != NULL) {
*n_aliases = priv->_aliases_len;
}
return (const gchar **)priv->_aliases;
}
/**
* matrix_event_room_aliases_set_aliases:
* @event: a #MatrixEventRoomAliases
* @aliases: a list of aliases
* @n_aliases: the length of @aliases
*
* Set the list of aliases in @event.
*/
void
matrix_event_room_aliases_set_aliases(MatrixEventRoomAliases *matrix_event_room_aliases, const gchar **aliases, int n_aliases)
{
MatrixEventRoomAliasesPrivate *priv;
g_return_if_fail(matrix_event_room_aliases != NULL);
priv = matrix_event_room_aliases_get_instance_private(matrix_event_room_aliases);
for (gint i = 0; i < priv->_aliases_len; i++) {
g_free(priv->_aliases[i]);
}
g_free(priv->_aliases);
priv->_aliases = g_new(gchar *, n_aliases);
for (gint i = 0; i < n_aliases; i++) {
priv->_aliases[i] = g_strdup(aliases[i]);
}
}
static void
matrix_event_room_aliases_finalize(GObject *gobject)
{
MatrixEventRoomAliasesPrivate *priv = matrix_event_room_aliases_get_instance_private(MATRIX_EVENT_ROOM_ALIASES(gobject));
for (gint i = 0; i < priv->_aliases_len; i++) {
g_free(priv->_aliases[i]);
}
g_free(priv->_aliases);
G_OBJECT_CLASS(matrix_event_room_aliases_parent_class)->finalize(gobject);
}
static void
matrix_event_room_aliases_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomAliases *self = MATRIX_EVENT_ROOM_ALIASES(gobject);
switch (property_id) {
case PROP_ALIASES:
g_value_set_boxed(value, matrix_event_room_aliases_get_aliases(self, NULL));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_aliases_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomAliases *self = MATRIX_EVENT_ROOM_ALIASES(gobject);
switch (property_id) {
case PROP_ALIASES:
{
gpointer boxed;
boxed = g_value_get_boxed(value);
matrix_event_room_aliases_set_aliases(self, boxed, (boxed == NULL) ? 0 : g_strv_length (boxed));
break;
}
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_aliases_class_init(MatrixEventRoomAliasesClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_aliases_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_aliases_real_to_json;
G_OBJECT_CLASS (klass)->get_property = matrix_event_room_aliases_get_property;
G_OBJECT_CLASS (klass)->set_property = matrix_event_room_aliases_set_property;
G_OBJECT_CLASS (klass)->finalize = matrix_event_room_aliases_finalize;
/**
* MatrixEventRoomAliases:aliases:
*
* A list of room aliases.
*/
matrix_event_room_aliases_properties[PROP_ALIASES] = g_param_spec_boxed(
"aliases", "aliases", "aliases",
G_TYPE_STRV,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ALIASES, matrix_event_room_aliases_properties[PROP_ALIASES]);
}
static void
matrix_event_room_aliases_init(MatrixEventRoomAliases *matrix_event_room_aliases)
{}

View File

@@ -0,0 +1,41 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_ALIASES_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_ALIASES_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_ROOM_ALIASES matrix_event_room_aliases_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomAliases, matrix_event_room_aliases, MATRIX_EVENT, ROOM_ALIASES, MatrixEventState);
struct _MatrixEventRoomAliasesClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomAliases* matrix_event_room_aliases_new (void);
MatrixEventRoomAliases* matrix_event_room_aliases_construct (GType object_type);
const gchar** matrix_event_room_aliases_get_aliases (MatrixEventRoomAliases *event, int *n_aliases);
void matrix_event_room_aliases_set_aliases (MatrixEventRoomAliases *event, const gchar **aliases, int n_aliases);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_ALIASES_H__ */

View File

@@ -1,87 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.aliases event.
*
* This event is sent by a homeserver directly to inform of changes to
* the list of aliases it knows about for that room.
*
* The state_key for this event is set to the homeserver which owns
* the room alias.
*
* The entire set of known aliases for the room is the union of all
* the m.room.aliases events, one for each homeserver. Clients should
* check the validity of any room alias given in this list before
* presenting it to the user as trusted fact. The lists given by this
* event should be considered simply as advice on which aliases might
* exist, for which the client can perform the lookup to confirm
* whether it receives the correct room ID.
*/
public class Matrix.Event.RoomAliases : Matrix.Event.State {
/**
* A list of room aliases.
*/
public string[] aliases { get; set; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("aliases")) != null) {
_aliases = new string[node.get_array().get_length()];
node.get_array().foreach_element((ary, idx, member_node) => {
_aliases[idx] = member_node.get_string();
});
} else if (Config.DEBUG) {
warning("content.aliases is missing from a m.room.aliases event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_aliases.length == 0) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.aliases event without aliases");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
var aliases_ary = new Json.Array();
foreach (var entry in _aliases) {
aliases_ary.add_string_element(entry);
}
var aliases_node = new Json.Node(Json.NodeType.ARRAY);
aliases_node.set_array(aliases_ary);
content_root.set_member("aliases", aliases_node);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,512 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-avatar.h"
#include "config.h"
/**
* SECTION:matrix-event-room-avatar
* @short_description: event holding the room avatar
*
* This is the default handler for `m.room.avatar` events.
*
* A picture that is associated with the room. This can be displayed alongside the room
* information.
*/
enum {
PROP_0,
PROP_URL,
PROP_THUMBNAIL_URL,
PROP_INFO,
PROP_THUMBNAIL_INFO,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_avatar_properties[NUM_PROPERTIES];
typedef struct {
gchar* _url;
gchar* _thumbnail_url;
MatrixImageInfo* _info;
MatrixImageInfo* _thumbnail_info;
} MatrixEventRoomAvatarPrivate;
/**
* MatrixEventRoomAvatar:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomAvatar, matrix_event_room_avatar, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_avatar_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomAvatarPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_avatar_get_instance_private(MATRIX_EVENT_ROOM_AVATAR(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if (DEBUG) {
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const char *sk = json_node_get_string(node);
if ((sk != NULL) && (*sk != 0)) {
g_warning("state_key of a m.room.avatar event is non-empty");
}
}
}
if ((node = json_object_get_member(content_root, "url")) != NULL) {
g_free(priv->_url);
priv->_url = g_strdup(json_node_get_string(node));
} else {
g_warning("content.url is missing from a m.room.avatar event");
}
if ((node = json_object_get_member(content_root, "thumbnail_url")) != NULL) {
g_free(priv->_thumbnail_url);
priv->_thumbnail_url = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(content_root, "info")) != NULL) {
matrix_image_info_unref(priv->_info);
priv->_info = matrix_image_info_new();
matrix_image_info_set_from_json(priv->_info, node);
}
if ((node = json_object_get_member(content_root, "thumbnail_info")) != NULL) {
matrix_image_info_unref(priv->_thumbnail_info);
priv->_thumbnail_info = matrix_image_info_new();
matrix_image_info_set_from_json(priv->_thumbnail_info, node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_avatar_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_avatar_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomAvatarPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
const gchar *state_key;
GError *inner_error = NULL;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_avatar_get_instance_private(MATRIX_EVENT_ROOM_AVATAR(matrix_event_base));
if (priv->_url == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.avatar event without url");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.avatar event with a non-empty state_key");
return;
}
json_object_set_string_member(content_root, "url", priv->_url);
if (priv->_thumbnail_url != NULL) {
json_object_set_string_member(content_root, "thumbnail_url", priv->_thumbnail_url);
}
if (priv->_info != NULL) {
node = matrix_image_info_get_json_node(priv->_info, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return;
}
json_object_set_member(content_root, "info", node);
}
if (priv->_thumbnail_info != NULL) {
node = matrix_image_info_get_json_node(priv->_thumbnail_info, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return;
}
json_object_set_member(content_root, "thumbnail_info", node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_avatar_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomAvatar *
matrix_event_room_avatar_construct(GType object_type)
{
return (MatrixEventRoomAvatar *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_avatar_new:
*
* Create a new #MatrixEventRoomAvatar object.
*
* Returns: (transfer full): a new #MatrixEventRoomAvatar object
*/
MatrixEventRoomAvatar *
matrix_event_room_avatar_new(void)
{
return matrix_event_room_avatar_construct(MATRIX_EVENT_TYPE_ROOM_AVATAR);
}
/**
* matrix_event_room_avatar_get_url:
* @event: a #MatrixEventRoomAvatar
*
* Get the URL of the room avatar from @event.
*
* The returned value is owned by @event and should no be freed.
*
* Returns: (transfer none) (nullable): an avatar URL
*/
const gchar *
matrix_event_room_avatar_get_url(MatrixEventRoomAvatar *matrix_event_room_avatar)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_val_if_fail(matrix_event_room_avatar != NULL, NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
return priv->_url;
}
/**
* matrix_event_room_avatar_set_url:
* @event: a #MatrixEventRoomAvatar
* @url: (transfer none) (nullable): an URL to set as the room avatar
*
* Set the room avatar URL.
*/
void
matrix_event_room_avatar_set_url(MatrixEventRoomAvatar *matrix_event_room_avatar, const gchar *url)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_if_fail(matrix_event_room_avatar != NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
if (g_strcmp0(url, priv->_url) != 0) {
g_free(priv->_url);
priv->_url = g_strdup(url);
g_object_notify_by_pspec((GObject *)matrix_event_room_avatar, matrix_event_room_avatar_properties[PROP_URL]);
}
}
/**
* matrix_event_room_avatar_get_thumbnail_url:
* @event: a #MatrixEventRoomAvatar
*
* Get the URL of the avatars thumbnail.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the URL of the avatar thumbnail
*/
const gchar *
matrix_event_room_avatar_get_thumbnail_url(MatrixEventRoomAvatar *matrix_event_room_avatar)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_val_if_fail(matrix_event_room_avatar != NULL, NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
return priv->_thumbnail_url;
}
/**
* matrix_event_room_avatar_set_thumbnail_url:
* @event: a #MatrixEventRoomAvatar
* @thumbnail_url: (transfer none) (nullable): the URL of the room avatars thumbnail
*
* Set the URL of the room avatars thumbnail.
*/
void
matrix_event_room_avatar_set_thumbnail_url(MatrixEventRoomAvatar *matrix_event_room_avatar, const gchar *thumbnail_url)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_if_fail(matrix_event_room_avatar != NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
if (g_strcmp0(thumbnail_url, priv->_thumbnail_url) != 0) {
g_free(priv->_thumbnail_url);
priv->_thumbnail_url = g_strdup(thumbnail_url);
g_object_notify_by_pspec((GObject *)matrix_event_room_avatar, matrix_event_room_avatar_properties[PROP_THUMBNAIL_URL]);
}
}
/**
* matrix_event_room_avatar_get_info:
* @event: a #MatrixEventRoomAvatar
*
* Get the image info for the room avatar.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the image info for the room avatar image.
*/
MatrixImageInfo *
matrix_event_room_avatar_get_info(MatrixEventRoomAvatar *matrix_event_room_avatar)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_val_if_fail(matrix_event_room_avatar != NULL, NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
return priv->_info;
}
/**
* matrix_event_room_avatar_set_info:
* @event: a #MatrixEventRoomAvatar
* @info: a #MatrixImageInfo
*
* Set the image information for the avatar image.
*/
void
matrix_event_room_avatar_set_info(MatrixEventRoomAvatar *matrix_event_room_avatar, MatrixImageInfo *info)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_if_fail(matrix_event_room_avatar != NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
if (priv->_info != info) {
matrix_image_info_unref(priv->_info);
priv->_info = matrix_image_info_ref(info);
g_object_notify_by_pspec((GObject *)matrix_event_room_avatar, matrix_event_room_avatar_properties[PROP_INFO]);
}
}
/**
* matrix_event_room_avatar_get_thumbnail_info:
* @event: a #MatrixEventRoomAvatar
*
* Get the image info for the room avatars thumbnail.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the image info for the avatars thumbnail
*/
MatrixImageInfo *
matrix_event_room_avatar_get_thumbnail_info(MatrixEventRoomAvatar *matrix_event_room_avatar)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_val_if_fail(matrix_event_room_avatar != NULL, NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
return priv->_thumbnail_info;
}
/**
* matrix_event_room_avatar_set_thumbnail_info:
* @event: a #MatrixEventRoomAvatar
* @thumbnail_info: (transfer none) (nullable): a #MatrixImageInfo
*
* Set the image info for the room avatars thumbnail.
*/
void
matrix_event_room_avatar_set_thumbnail_info(MatrixEventRoomAvatar *matrix_event_room_avatar, MatrixImageInfo *thumbnail_info)
{
MatrixEventRoomAvatarPrivate *priv;
g_return_if_fail(matrix_event_room_avatar != NULL);
priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
if (priv->_thumbnail_info != thumbnail_info) {
matrix_image_info_unref(priv->_thumbnail_info);
priv->_thumbnail_info = matrix_image_info_ref(thumbnail_info);
g_object_notify_by_pspec((GObject *)matrix_event_room_avatar, matrix_event_room_avatar_properties[PROP_THUMBNAIL_INFO]);
}
}
static void
matrix_event_room_avatar_finalize(GObject *gobject)
{
MatrixEventRoomAvatarPrivate *priv = matrix_event_room_avatar_get_instance_private(MATRIX_EVENT_ROOM_AVATAR(gobject));
g_free(priv->_url);
g_free(priv->_thumbnail_url);
matrix_image_info_unref(priv->_info);
matrix_image_info_unref(priv->_thumbnail_info);
G_OBJECT_CLASS(matrix_event_room_avatar_parent_class)->finalize(gobject);
}
static void
matrix_event_room_avatar_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomAvatar *matrix_event_room_avatar = MATRIX_EVENT_ROOM_AVATAR(gobject);
switch (property_id) {
case PROP_URL:
g_value_set_string(value, matrix_event_room_avatar_get_url(matrix_event_room_avatar));
break;
case PROP_THUMBNAIL_URL:
g_value_set_string(value, matrix_event_room_avatar_get_thumbnail_url(matrix_event_room_avatar));
break;
case PROP_INFO:
g_value_set_boxed(value, matrix_event_room_avatar_get_info(matrix_event_room_avatar));
break;
case PROP_THUMBNAIL_INFO:
g_value_set_boxed(value, matrix_event_room_avatar_get_thumbnail_info(matrix_event_room_avatar));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_avatar_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomAvatar *matrix_event_room_avatar = MATRIX_EVENT_ROOM_AVATAR(gobject);
switch (property_id) {
case PROP_URL:
matrix_event_room_avatar_set_url(matrix_event_room_avatar, g_value_get_string(value));
break;
case PROP_THUMBNAIL_URL:
matrix_event_room_avatar_set_thumbnail_url(matrix_event_room_avatar, g_value_get_string(value));
break;
case PROP_INFO:
matrix_event_room_avatar_set_info(matrix_event_room_avatar, g_value_get_boxed(value));
break;
case PROP_THUMBNAIL_INFO:
matrix_event_room_avatar_set_thumbnail_info(matrix_event_room_avatar, g_value_get_boxed(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_avatar_class_init(MatrixEventRoomAvatarClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_avatar_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_avatar_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_avatar_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_avatar_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_avatar_finalize;
/**
* MatrixEventRoomAvatar:url:
*
* The URL to the image.
*/
matrix_event_room_avatar_properties[PROP_URL] = g_param_spec_string(
"url", "url", "url",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_URL, matrix_event_room_avatar_properties[PROP_URL]);
/**
* MatrixEventRoomAvatar:thumbnail-url:
*
* The URL to the thumbnail of the image.
*/
matrix_event_room_avatar_properties[PROP_THUMBNAIL_URL] = g_param_spec_string(
"thumbnail-url", "thumbnail-url", "thumbnail-url",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_THUMBNAIL_URL, matrix_event_room_avatar_properties[PROP_THUMBNAIL_URL]);
/**
* MatrixEventRoomAvatar:info:
*
* The image info for the room avatar.
*/
matrix_event_room_avatar_properties[PROP_INFO] = g_param_spec_boxed(
"info", "info", "info",
MATRIX_TYPE_IMAGE_INFO,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_INFO, matrix_event_room_avatar_properties[PROP_INFO]);
/**
* MatrixEventRoomAvatar:thumbnail-info:
*
* The image info for the room avatars thumbnail.
*/
matrix_event_room_avatar_properties[PROP_INFO] = g_param_spec_boxed(
"thumbnail-info", "thumbnail-info", "thumbnail-info",
MATRIX_TYPE_IMAGE_INFO,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_INFO, matrix_event_room_avatar_properties[PROP_INFO]);
}
static void
matrix_event_room_avatar_init(MatrixEventRoomAvatar *matrix_event_room_avatar)
{
MatrixEventRoomAvatarPrivate *priv = matrix_event_room_avatar_get_instance_private(matrix_event_room_avatar);
priv->_url = NULL;
priv->_thumbnail_url = NULL;
priv->_info = NULL;
priv->_thumbnail_info = NULL;
}

View File

@@ -0,0 +1,48 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_AVATAR_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_AVATAR_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
# include "matrix-types.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_ROOM_AVATAR matrix_event_room_avatar_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomAvatar, matrix_event_room_avatar, MATRIX_EVENT, ROOM_AVATAR, MatrixEventState);
struct _MatrixEventRoomAvatarClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomAvatar* matrix_event_room_avatar_new (void);
MatrixEventRoomAvatar* matrix_event_room_avatar_construct (GType object_type);
const gchar *matrix_event_room_avatar_get_url (MatrixEventRoomAvatar *event);
void matrix_event_room_avatar_set_url (MatrixEventRoomAvatar *event, const gchar *url);
const gchar *matrix_event_room_avatar_get_thumbnail_url (MatrixEventRoomAvatar *event);
void matrix_event_room_avatar_set_thumbnail_url (MatrixEventRoomAvatar *event, const gchar *thumbnail_url);
MatrixImageInfo *matrix_event_room_avatar_get_info (MatrixEventRoomAvatar *event);
void matrix_event_room_avatar_set_info (MatrixEventRoomAvatar *event, MatrixImageInfo *info);
MatrixImageInfo *matrix_event_room_avatar_get_thumbnail_info (MatrixEventRoomAvatar *event);
void matrix_event_room_avatar_set_thumbnail_info (MatrixEventRoomAvatar *event, MatrixImageInfo *thumbnail_info);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_AVATAR_H__ */

View File

@@ -1,121 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.avatar event
*
* A picture that is associated with the room. This can be displayed
* alongside the room information.
*/
public class Matrix.Event.RoomAvatar : Matrix.Event.State {
/**
* The URL to the image.
*/
public string? url { get; set; default = null; }
/**
* The URL to the thumbnail of the image.
*/
public string? thumbnail_url { get; set; default = null; }
/**
* Metadata about the image referred to in url.
*/
public ImageInfo? info { get; set; default = null; }
/**
* Metadata about the image referred to in thumbnail_url.
*/
public ImageInfo? thumbnail_info { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node;
if (Config.DEBUG) {
if ((node = root.get_member("state_key")) != null) {
var sk = node.get_string();
if (sk != "") {
warning("state_key of a m.room.avatar event is non-empty");
}
}
}
if ((node = content_root.get_member("url")) != null) {
_url = node.get_string();
} else {
warning("content.url is missing from a m.room.avatar event");
}
if ((node = content_root.get_member("thumbnail_url")) != null) {
_thumbnail_url = node.get_string();
}
if ((node = content_root.get_member("info")) != null) {
_info = ImageInfo();
_info.set_from_json(node);
}
if ((node = content_root.get_member("thumbnail_info")) != null) {
_thumbnail_info = ImageInfo();
_thumbnail_info.set_from_json(node);
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_url == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.avatar event without url");
}
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.avatar event with a non-empty state_key");
}
content_root.set_string_member("url", _url);
if (_thumbnail_url != null) {
content_root.set_string_member("thumbnail_url", _thumbnail_url);
}
if (_info != null) {
content_root.set_member("info", _info.get_json_node());
}
if (_thumbnail_info != null) {
content_root.set_member("thumbnail_info",
_thumbnail_info.get_json_node());
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,672 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-base.h"
#include "config.h"
/**
* SECTION:matrix-event-room-base
* @short_description: abstract base class for room events
* @title: room event base class
*
* #MatrixEventRoom is the abstract base class for room events. It handles the `event_id`,
* `room_id`, `sender`, `age`, `redacted_because`, and `transaction_id` field of an events
* JSON representation, so subclasses dont have to care about them.
*/
enum {
PROP_0,
PROP_EVENT_ID,
PROP_ROOM_ID,
PROP_SENDER,
PROP_AGE,
PROP_REDACTED_BECAUSE,
PROP_TRANSACTION_ID,
NUM_PROPS
};
static GParamSpec* matrix_event_room_properties[NUM_PROPS];
typedef struct {
gchar* _event_id;
gchar* _room_id;
gchar* _sender;
glong _age;
gchar* _redacted_because;
gchar* _transaction_id;
} MatrixEventRoomPrivate;
/**
* MatrixEventRoom:
*
* Abstract base class for room events.
*/
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(MatrixEventRoom, matrix_event_room, MATRIX_EVENT_TYPE_BASE);
static void
matrix_event_room_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoom *matrix_event_room;
MatrixEventRoomPrivate *priv;
JsonObject *root;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
matrix_event_room = MATRIX_EVENT_ROOM(matrix_event_base);
priv = matrix_event_room_get_instance_private(matrix_event_room);
root = json_node_get_object(json_data);
if ((node = json_object_get_member (root, "event_id")) != NULL) {
g_free(priv->_event_id);
priv->_event_id = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning ("matrix-event-room-base.vala:71: event_id is missing from a Room event");
}
if ((node = json_object_get_member(root, "room_id")) != NULL) {
g_free(priv->_room_id);
priv->_room_id = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning ("matrix-event-room-base.vala:77: room_id is missing from a Room event");
}
if ((node = json_object_get_member(root, "sender")) != NULL) {
g_free(priv->_sender);
priv->_sender = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning ("matrix-event-room-base.vala:83: sender is missing from a Room event");
}
if ((node = json_object_get_member(root, "unsigned")) != NULL) {
JsonObject* unsigned_root = NULL;
unsigned_root = json_node_get_object(node);
if ((node = json_object_get_member (unsigned_root, "age")) != NULL) {
priv->_age = json_node_get_int(node);
}
if ((node = json_object_get_member(unsigned_root, "redacted_because")) != NULL) {
g_free(priv->_redacted_because);
priv->_redacted_because = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(unsigned_root, "transaction_id")) != NULL) {
g_free(priv->_transaction_id);
priv->_transaction_id = g_strdup(json_node_get_string(node));
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
json_object_unref(root);
json_node_unref(node);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return;
}
}
static void
matrix_event_room_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoom *matrix_event_room;
MatrixEventRoomPrivate *priv;
JsonObject *root_obj;
JsonObject *unsigned_obj;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
matrix_event_room = MATRIX_EVENT_ROOM(matrix_event_base);
priv = matrix_event_room_get_instance_private(matrix_event_room);
root_obj = json_node_get_object (json_data);
if (priv->_event_id != NULL) {
json_object_set_string_member (root_obj, "event_id", priv->_event_id);
}
if (priv->_room_id!= NULL) {
json_object_set_string_member(root_obj, "room_id", priv->_room_id);
}
if (priv->_sender != NULL) {
json_object_set_string_member (root_obj, "sender", priv->_sender);
}
unsigned_obj = json_object_new();
if (priv->_age >= 0) {
json_object_set_int_member (unsigned_obj, "age", priv->_age);
}
if (priv->_redacted_because != NULL) {
json_object_set_string_member (unsigned_obj, "redacted_because", priv->_redacted_because);
}
if (priv->_transaction_id != NULL) {
json_object_set_string_member (unsigned_obj, "transaction_id", priv->_transaction_id);
}
if (json_object_get_size(unsigned_obj) > 0) {
JsonNode* unsigned_node = NULL;
unsigned_node = json_node_new (JSON_NODE_OBJECT);
json_node_set_object (unsigned_node, unsigned_obj);
json_object_set_member (root_obj, "unsigned", unsigned_node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_parent_class)->to_json(MATRIX_EVENT_BASE(matrix_event_base), json_data, &inner_error);
json_object_unref(unsigned_obj);
json_object_unref(root_obj);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return;
}
}
MatrixEventRoom *
matrix_event_room_construct(GType object_type)
{
return (MatrixEventRoom *)matrix_event_base_construct(object_type);
}
/**
* matrix_event_room_get_event_id:
* @event: a #MatrixEventRoom derived object
*
* Get the event ID.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the event ID
*/
const gchar *
matrix_event_room_get_event_id(MatrixEventRoom *matrix_event_room)
{
MatrixEventRoomPrivate *priv;
g_return_val_if_fail(matrix_event_room != NULL, NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
return priv->_event_id;
}
/**
* matrix_event_room_set_event_id:
* @event: a #MatrixEventRoom derived object
* @event_id: (transfer none) (nullable): an event ID
*
* Set the event ID in @event.
*
* As the event sending process will strip away this field, setting the event ID is usually
* useless.
*/
void
matrix_event_room_set_event_id(MatrixEventRoom *matrix_event_room, const gchar *event_id)
{
MatrixEventRoomPrivate *priv;
g_return_if_fail(matrix_event_room != NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
if (g_strcmp0(event_id, priv->_event_id) != 0) {
g_free(priv->_event_id);
priv->_event_id = g_strdup(event_id);
g_object_notify_by_pspec((GObject *)matrix_event_room, matrix_event_room_properties[PROP_EVENT_ID]);
}
}
/**
* matrix_event_room_get_room_id:
* @event: a #MatrixEventRoom derived object
*
* Get the room ID from @event.
*
* The returned value is owned by @event, and should not be freed.
*
* Returns: (transfer none) (nullable): the room ID
*/
const gchar *
matrix_event_room_get_room_id(MatrixEventRoom *matrix_event_room)
{
MatrixEventRoomPrivate *priv;
g_return_val_if_fail(matrix_event_room != NULL, NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
return priv->_room_id;
}
/**
* matrix_event_room_set_room_id:
* @event: a #MatrixEventRoom derived object
* @room_id: (transfer none) (nullable): a room ID
*
* Set the room ID for @event.
*
* This field is actually the target of any message, so it is really important to set
* correctly. Room IDs, as per the Matrix specification, look like
* `!random-string:homeserver`. This function doesnt check for validity, though.
*/
void
matrix_event_room_set_room_id(MatrixEventRoom *matrix_event_room, const gchar *room_id)
{
MatrixEventRoomPrivate *priv;
g_return_if_fail(matrix_event_room != NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
if (g_strcmp0(room_id, priv->_room_id) != 0) {
g_free(priv->_room_id);
priv->_room_id = g_strdup(room_id);
g_object_notify_by_pspec((GObject *)matrix_event_room, matrix_event_room_properties[PROP_ROOM_ID]);
}
}
/**
* matrix_event_room_get_sender:
* @event: a #MatrixEventRoom derived object
*
* Get the user ID of @events sender.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a user ID in MXID format
*/
const gchar *
matrix_event_room_get_sender(MatrixEventRoom *matrix_event_room)
{
MatrixEventRoomPrivate *priv;
g_return_val_if_fail(matrix_event_room != NULL, NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
return priv->_sender;
}
/**
* matrix_event_room_set_sender:
* @event: a #MatrixEventRoom derived object
* @sender: (transfer none) (nullable): a user ID in MXID format
*
* Set the sender of @event.
*
* @sender must be in MXID format (`\@user_id:homeserver`). This function doesnt check for
* user ID validity.
*/
void
matrix_event_room_set_sender(MatrixEventRoom *matrix_event_room, const gchar *sender)
{
MatrixEventRoomPrivate *priv;
g_return_if_fail(matrix_event_room != NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
if (g_strcmp0(sender, priv->_sender) != 0) {
g_free(priv->_sender);
priv->_sender = g_strdup(sender);
g_object_notify_by_pspec((GObject *)matrix_event_room, matrix_event_room_properties[PROP_SENDER]);
}
}
/**
* matrix_event_room_get_age:
* @event: a #MatrixEventRoom derived object
*
* Get the age of the event.
*
* The age is reported by the homeserver, not calculated by this library.
*
* Returns: the age, in milliseconds
*/
glong
matrix_event_room_get_age (MatrixEventRoom *matrix_event_room) {
MatrixEventRoomPrivate *priv;
g_return_val_if_fail(matrix_event_room != NULL, -1);
priv = matrix_event_room_get_instance_private(matrix_event_room);
return priv->_age;
}
/**
* matrix_event_room_set_age:
* @event: a #MatrixEventRoom derived object
* @age: the age of the event, in milliseconds
*
* Set the age of @event.
*
* As age is calculated by the homeserver based on the timestamp it received the event,
* setting this property explicitly has no point.
*/
void
matrix_event_room_set_age(MatrixEventRoom *matrix_event_room, glong age)
{
MatrixEventRoomPrivate *priv;
g_return_if_fail(matrix_event_room != NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
if (priv->_age != age) {
priv->_age = age;
g_object_notify_by_pspec((GObject *)matrix_event_room, matrix_event_room_properties[PROP_AGE]);
}
}
/**
* matrix_event_room_get_redacted_because:
* @event: a #MatrixEventRoom derived object
*
* Get the redaction reason of @event.
*
* This will be %NULL if the event is not redacted, but may also be %NULL if the event is
* redacted without reason.
*
* The value returned is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the redaction reason
*/
const gchar *
matrix_event_room_get_redacted_because(MatrixEventRoom *matrix_event_room) {
MatrixEventRoomPrivate *priv;
g_return_val_if_fail(matrix_event_room != NULL, NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
return priv->_redacted_because;
}
/**
* matrix_event_room_set_redacted_because:
* @event: a #MatrixEventRoom derived object
* @redacted_because: (transfer none) (nullable): the reason @event got redacted
*
* Set the redaction reason for @event.
*
* Redacting events must be done via the corresponding API (eg. matrix_api_redact_event()).
* Merely setting this field has no effect on the Matrix network.
*/
void
matrix_event_room_set_redacted_because(MatrixEventRoom *matrix_event_room, const gchar *redacted_because)
{
MatrixEventRoomPrivate *priv;
g_return_if_fail(matrix_event_room != NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
if (g_strcmp0(redacted_because, priv->_redacted_because) != 0) {
g_free(priv->_redacted_because);
priv->_redacted_because = g_strdup(redacted_because);
g_object_notify_by_pspec((GObject *)matrix_event_room, matrix_event_room_properties[PROP_REDACTED_BECAUSE]);
}
}
/**
* matrix_event_room_get_transaction_id:
* @event: a #MatrixEventRoom derived object
*
* Get the transaction ID of @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the transaction ID
*/
const gchar *
matrix_event_room_get_transaction_id(MatrixEventRoom *matrix_event_room)
{
MatrixEventRoomPrivate *priv;
g_return_val_if_fail(matrix_event_room != NULL, NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
return priv->_transaction_id;
}
/**
* matrix_event_room_set_transaction_id:
* @event: a #MatrixEventRoom derived object
* @transaction_id: (transfer none) (nullable): a transction ID
*
* Set the transaction ID of the event.
*/
void
matrix_event_room_set_transaction_id(MatrixEventRoom *matrix_event_room, const gchar *transaction_id)
{
MatrixEventRoomPrivate *priv;
g_return_if_fail(matrix_event_room != NULL);
priv = matrix_event_room_get_instance_private(matrix_event_room);
if (g_strcmp0(transaction_id, priv->_transaction_id) != 0) {
g_free(priv->_transaction_id);
priv->_transaction_id = g_strdup(transaction_id);
g_object_notify_by_pspec((GObject *)matrix_event_room, matrix_event_room_properties[PROP_TRANSACTION_ID]);
}
}
static void
matrix_event_room_get_property(GObject *gobject, guint property_id, GValue* value, GParamSpec* pspec)
{
MatrixEventRoomPrivate *priv = matrix_event_room_get_instance_private(MATRIX_EVENT_ROOM(gobject));
switch (property_id) {
case PROP_EVENT_ID:
g_value_set_string(value, priv->_event_id);
break;
case PROP_ROOM_ID:
g_value_set_string(value, priv->_room_id);
break;
case PROP_SENDER:
g_value_set_string(value, priv->_sender);
break;
case PROP_AGE:
g_value_set_long(value, priv->_age);
break;
case PROP_REDACTED_BECAUSE:
g_value_set_string(value, priv->_redacted_because);
break;
case PROP_TRANSACTION_ID:
g_value_set_string(value, priv->_transaction_id);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_set_property(GObject *gobject, guint property_id, const GValue* value, GParamSpec* pspec)
{
MatrixEventRoom *matrix_event_room = MATRIX_EVENT_ROOM(gobject);
switch (property_id) {
case PROP_EVENT_ID:
matrix_event_room_set_event_id(matrix_event_room, g_value_get_string(value));
break;
case PROP_ROOM_ID:
matrix_event_room_set_room_id(matrix_event_room, g_value_get_string(value));
break;
case PROP_SENDER:
matrix_event_room_set_sender(matrix_event_room, g_value_get_string(value));
break;
case PROP_AGE:
matrix_event_room_set_age(matrix_event_room, g_value_get_long(value));
break;
case PROP_REDACTED_BECAUSE:
matrix_event_room_set_redacted_because(matrix_event_room, g_value_get_string(value));
break;
case PROP_TRANSACTION_ID:
matrix_event_room_set_transaction_id(matrix_event_room, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_finalize(GObject *gobject)
{
MatrixEventRoomPrivate *priv = matrix_event_room_get_instance_private(MATRIX_EVENT_ROOM(gobject));
g_free(priv->_event_id);
g_free(priv->_room_id);
g_free(priv->_sender);
g_free(priv->_redacted_because);
g_free(priv->_transaction_id);
G_OBJECT_CLASS(matrix_event_room_parent_class)->finalize(gobject);
}
static void
matrix_event_room_class_init(MatrixEventRoomClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_real_to_json;
G_OBJECT_CLASS (klass)->get_property = matrix_event_room_get_property;
G_OBJECT_CLASS (klass)->set_property = matrix_event_room_set_property;
G_OBJECT_CLASS (klass)->finalize = matrix_event_room_finalize;
/**
* MatrixEventRoom:event-id:
*
* A globally unique event ID. Required.
*/
matrix_event_room_properties[PROP_EVENT_ID] = g_param_spec_string(
"event-id", "event-id", "event-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_EVENT_ID, matrix_event_room_properties[PROP_EVENT_ID]);
/**
* MatrixEventRoom:room-id:
*
* The ID of the room associated with this event. Required, but it
* may be stripped by HS implementations from some APIs if they
* reside under a key marked with the room ID.
*/
matrix_event_room_properties[PROP_ROOM_ID] = g_param_spec_string(
"room-id", "room-id", "room-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_ROOM_ID, matrix_event_room_properties[PROP_ROOM_ID]);
/**
* MatrixEventRoom:sender:
*
* The fully qualified Matrix ID of the user who sent the
* event. Required.
*/
matrix_event_room_properties[PROP_SENDER] = g_param_spec_string(
"sender", "sender", "sender",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_SENDER, matrix_event_room_properties[PROP_SENDER]);
/**
* MatrixEventRoom:age:
*
* The time, in milliseconds, that has elapsed since the event was sent. This is part of
* the unsigned event data.
*
* This value will be omitted from the generated event JSON if less than zero.
*/
matrix_event_room_properties[PROP_AGE] = g_param_spec_long(
"age", "age", "age",
G_MINLONG, G_MAXLONG, 0,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AGE, matrix_event_room_properties[PROP_AGE]);
/**
* MatrixEventRoom:redacted-because:
*
* The reason this event was redacted, if it was redacted.
*/
matrix_event_room_properties[PROP_REDACTED_BECAUSE] = g_param_spec_string(
"redacted-because", "redacted-because", "redacted-because",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_REDACTED_BECAUSE, matrix_event_room_properties[PROP_REDACTED_BECAUSE]);
/**
* MatrixEventRoom:transaction-id:
*
* The client-supplied transaction ID. This should only be set if
* the client being given the event is the same one which sent it.
*/
matrix_event_room_properties[PROP_TRANSACTION_ID] = g_param_spec_string(
"transaction-id", "transaction-id", "transaction-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TRANSACTION_ID, matrix_event_room_properties[PROP_TRANSACTION_ID]);
}
static void
matrix_event_room_init(MatrixEventRoom *matrix_event_room)
{
MatrixEventRoomPrivate *priv = matrix_event_room_get_instance_private(matrix_event_room);
priv->_event_id = NULL;
priv->_room_id = NULL;
priv->_sender = NULL;
priv->_age = 0;
priv->_redacted_because = NULL;
priv->_transaction_id = NULL;
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_BASE_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_BASE_H__
# include <glib-object.h>
# include "matrix-event-base.h"
# define MATRIX_EVENT_TYPE_ROOM matrix_event_room_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoom, matrix_event_room, MATRIX_EVENT, ROOM, MatrixEventBase);
struct _MatrixEventRoomClass {
MatrixEventBaseClass parent_class;
};
MatrixEventRoom *matrix_event_room_construct(GType object_type);
const gchar *matrix_event_room_get_event_id(MatrixEventRoom *event);
void matrix_event_room_set_event_id(MatrixEventRoom *event, const gchar *event_id);
const gchar *matrix_event_room_get_room_id(MatrixEventRoom *event);
void matrix_event_room_set_room_id(MatrixEventRoom *event, const gchar *room_id);
const gchar *matrix_event_room_get_sender(MatrixEventRoom *event);
void matrix_event_room_set_sender(MatrixEventRoom *event, const gchar *sender);
glong matrix_event_room_get_age(MatrixEventRoom *event);
void matrix_event_room_set_age(MatrixEventRoom *event, glong age);
const gchar *matrix_event_room_get_redacted_because(MatrixEventRoom *event);
void matrix_event_room_set_redacted_because(MatrixEventRoom *event, const gchar *redacted_because);
const gchar *matrix_event_room_get_transaction_id(MatrixEventRoom *event);
void matrix_event_room_set_transaction_id(MatrixEventRoom *event, const gchar *transaction_id);
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_BASE_H__ */

View File

@@ -1,147 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Abstract base class for room events.
*/
public abstract class Matrix.Event.Room : Matrix.Event.Base {
/**
* A globally unique event ID. Required.
*/
public string? event_id { get; set; default = null; }
/**
* The ID of the room associated with this event. Required, but it
* may be stripped by HS implementations from some APIs if they
* reside under a key marked with the room ID.
*/
public string? room_id { get; set; default = null; }
/**
* The fully qualified Matrix ID of the user who sent the
* event. Required.
*/
public string? sender { get; set; default = null; }
/**
* The time, in milliseconds, that has elapsed since the event was
* sent. This is part of the unsigned event data.
*
* This value will be omitted from the generated event JSON if
* less than zero.
*/
public long age { get; set; default = 0; }
/**
* The reason this event was redacted, if it was redacted.
*/
public string? redacted_because { get; set; default = null; }
/**
* The client-supplied transaction ID. This should only be set if
* the client being given the event is the same one which sent it.
*/
public string? transaction_id { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
Json.Node? node;
var root = json_data.get_object();
if ((node = root.get_member("event_id")) != null) {
_event_id = node.get_string();
} else if (Config.DEBUG) {
warning("event_id is missing from a Room event");
}
if ((node = root.get_member("room_id")) != null) {
_room_id = node.get_string();
} else if (Config.DEBUG) {
warning("room_id is missing from a Room event");
}
if ((node = root.get_member("sender")) != null) {
_sender = node.get_string();
} else if (Config.DEBUG) {
warning("sender is missing from a Room event");
}
if ((node = root.get_member("unsigned")) != null) {
var unsigned_root = node.get_object();
if ((node = unsigned_root.get_member("age")) != null) {
_age = (int)node.get_int();
}
if ((node = unsigned_root.get_member("redacted_because")) != null) {
_redacted_because = node.get_string();
}
if ((node = unsigned_root.get_member("transaction_id")) != null) {
_transaction_id = node.get_string();
}
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var root_obj = json_data.get_object();
if (event_id != null) {
root_obj.set_string_member("event_id", _event_id);
}
if (room_id != null) {
root_obj.set_string_member("room_id", _room_id);
}
if (sender != null) {
root_obj.set_string_member("sender", _sender);
}
var unsigned_obj = new Json.Object();
if (age >= 0) {
unsigned_obj.set_int_member("age", _age);
}
if (redacted_because != null) {
unsigned_obj.set_string_member("redacted_because",
_redacted_because);
}
if (transaction_id != null) {
unsigned_obj.set_string_member("transaction_id",
_transaction_id);
}
if (unsigned_obj.get_size() > 0) {
var unsigned_node = new Json.Node(Json.NodeType.OBJECT);
unsigned_node.set_object(unsigned_obj);
root_obj.set_member("unsigned", unsigned_node);
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,251 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-canonical-alias.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-canonical-alias
* @short_description: event to set a rooms canonical alias
*
* This is the default handler for `m.room.canonical_alias` events.
*
* This event is used to inform the room about which alias should be considered the canonical
* one. This could be for display purposes or as suggestion to users which alias to use to
* advertise the room.
*/
enum {
PROP_0,
PROP_CANONICAL_ALIAS,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_canonical_alias_properties[NUM_PROPERTIES];
typedef struct {
gchar* _canonical_alias;
} MatrixEventRoomCanonicalAliasPrivate;
/**
* MatrixEventRoomCanonicalAlias:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomCanonicalAlias, matrix_event_room_canonical_alias, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_canonical_alias_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomCanonicalAliasPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_canonical_alias_get_instance_private(MATRIX_EVENT_ROOM_CANONICAL_ALIAS(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
#if DEBUG
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key == 0)) {
g_warning("state_key of a m.room.canonical_alias event is non-empty");
}
}
#endif
if ((node = json_object_get_member(content_root, "alias")) != NULL) {
g_free(priv->_canonical_alias);
priv->_canonical_alias = g_strdup(json_node_get_string(node));
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_canonical_alias_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_canonical_alias_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomCanonicalAliasPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
const gchar *state_key;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_canonical_alias_get_instance_private(MATRIX_EVENT_ROOM_CANONICAL_ALIAS(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.canonical_alias event with a non-empty state_key");
return;
}
if (priv->_canonical_alias != NULL) {
json_object_set_string_member(content_root, "alias", priv->_canonical_alias);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_canonical_alias_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomCanonicalAlias *
matrix_event_room_canonical_alias_construct(GType object_type)
{
return (MatrixEventRoomCanonicalAlias *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_canonical_alias_new:
*
* Create a new #MatrixEventRoomCanonicalAlias object
*
* Returns: (transfer full): a new #MatrixEventRoomCanonicalAlias
*/
MatrixEventRoomCanonicalAlias *
matrix_event_room_canonical_alias_new(void)
{
return matrix_event_room_canonical_alias_construct(MATRIX_EVENT_TYPE_ROOM_CANONICAL_ALIAS);
}
/**
* matrix_event_room_canonical_alias_get_canonical_alias:
* @event: a #MatrixEventRoomCanonicalAlias
*
* Get the canonical alias from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the canonical alias
*/
const gchar *
matrix_event_room_canonical_alias_get_canonical_alias(MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias)
{
MatrixEventRoomCanonicalAliasPrivate *priv;
g_return_val_if_fail(matrix_event_room_canonical_alias != NULL, NULL);
priv = matrix_event_room_canonical_alias_get_instance_private(matrix_event_room_canonical_alias);
return priv->_canonical_alias;
}
/**
* matrix_event_room_canonical_alias_set_canonical_alias:
* @event: a #MatrixEventRoomCanonicalAlias
* @canonical_alias: (transfer none) (nullable): a canonical alias
*
* Set the canonical alias in @event.
*/
void
matrix_event_room_canonical_alias_set_canonical_alias(MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias, const gchar *canonical_alias)
{
MatrixEventRoomCanonicalAliasPrivate *priv;
g_return_if_fail(matrix_event_room_canonical_alias != NULL);
priv = matrix_event_room_canonical_alias_get_instance_private(matrix_event_room_canonical_alias);
if (g_strcmp0(canonical_alias, priv->_canonical_alias) != 0) {
g_free(priv->_canonical_alias);
priv->_canonical_alias = g_strdup(canonical_alias);
g_object_notify_by_pspec((GObject *)matrix_event_room_canonical_alias, matrix_event_room_canonical_alias_properties[PROP_CANONICAL_ALIAS]);
}
}
static void
matrix_event_room_canonical_alias_finalize(GObject *gobject)
{
MatrixEventRoomCanonicalAliasPrivate *priv = matrix_event_room_canonical_alias_get_instance_private(MATRIX_EVENT_ROOM_CANONICAL_ALIAS(gobject));
g_free(priv->_canonical_alias);
G_OBJECT_CLASS(matrix_event_room_canonical_alias_parent_class)->finalize(gobject);
}
static void
matrix_event_room_canonical_alias_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias = MATRIX_EVENT_ROOM_CANONICAL_ALIAS(gobject);
switch (property_id) {
case PROP_CANONICAL_ALIAS:
g_value_set_string(value, matrix_event_room_canonical_alias_get_canonical_alias(matrix_event_room_canonical_alias));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_canonical_alias_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias = MATRIX_EVENT_ROOM_CANONICAL_ALIAS(gobject);
switch (property_id) {
case PROP_CANONICAL_ALIAS:
matrix_event_room_canonical_alias_set_canonical_alias(matrix_event_room_canonical_alias, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_canonical_alias_class_init(MatrixEventRoomCanonicalAliasClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_canonical_alias_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_canonical_alias_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_canonical_alias_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_canonical_alias_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_canonical_alias_finalize;
/**
* MatrixEventRoomCanonicalAlias:canonical-alias:
*
* The canonical alias.
*/
matrix_event_room_canonical_alias_properties[PROP_CANONICAL_ALIAS] = g_param_spec_string(
"canonical-alias", "canonical-alias", "canonical-alias",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CANONICAL_ALIAS, matrix_event_room_canonical_alias_properties[PROP_CANONICAL_ALIAS]);
}
static void
matrix_event_room_canonical_alias_init(MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias)
{
MatrixEventRoomCanonicalAliasPrivate *priv = matrix_event_room_canonical_alias_get_instance_private(matrix_event_room_canonical_alias);
priv->_canonical_alias = NULL;
}

View File

@@ -0,0 +1,41 @@
/*
*This file is part of matrix-glib-sdk
*
*matrix-glib-sdk is free software: you can redistribute it and/or
*modify it under the terms of the GNU Lesser General Public
*License as published by the Free Software Foundation, either
*version 3 of the License, or (at your option) any later version.
*
*matrix-glib-sdk 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 Lesser General Public License for more details.
*
*You should have received a copy of the GNU Lesser General Public
*License along with matrix-glib-sdk. If not, see
*<http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_CANONICAL_ALIAS_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_CANONICAL_ALIAS_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_CANONICAL_ALIAS (matrix_event_room_canonical_alias_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomCanonicalAlias, matrix_event_room_canonical_alias, MATRIX_EVENT, ROOM_CANONICAL_ALIAS, MatrixEventState);
struct _MatrixEventRoomCanonicalAliasClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias_new (void);
MatrixEventRoomCanonicalAlias *matrix_event_room_canonical_alias_construct (GType object_type);
const gchar *matrix_event_room_canonical_alias_get_canonical_alias (MatrixEventRoomCanonicalAlias *event);
void matrix_event_room_canonical_alias_set_canonical_alias (MatrixEventRoomCanonicalAlias *event, const gchar *canonical_alias);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_CANONICAL_ALIAS_H__ */

View File

@@ -1,71 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.canonical_alias event
*
* This event is used to inform the room about which alias should be
* considered the canonical one. This could be for display purposes or
* as suggestion to users which alias to use to advertise the room.
*/
public class Matrix.Event.RoomCanonicalAlias : Matrix.Event.State {
/**
* The canonical alias.
*/
public string? canonical_alias { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.canonical_alias event is non-empty");
}
}
if ((node = content_root.get_member("alias")) != null) {
_canonical_alias = node.get_string();
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.canonical_alias event with a non-empty state_key");
}
if (_canonical_alias != null) {
content_root.set_string_member("alias", _canonical_alias);
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,332 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-create.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-create
* @short_description: event describing the creation of a room
*
* This is the default event handler for `m.room.create` events.
*
* This is the first event in a room and cannot be changed. It acts as the root of all other
* events.
*/
enum {
PROP_0,
PROP_CREATOR,
PROP_FEDERATE,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_create_properties[NUM_PROPERTIES];
typedef struct {
gchar* _creator;
gboolean _federate;
} MatrixEventRoomCreatePrivate;
/**
* MatrixEventRoomCreate:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomCreate, matrix_event_room_create, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_create_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomCreatePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_create_get_instance_private(MATRIX_EVENT_ROOM_CREATE(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
#if DEBUG
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key == 0)) {
g_warning("state_key of a m.room.create event is non-empty");
}
}
#endif
if ((node = json_object_get_member(content_root, "creator")) != NULL) {
g_free(priv->_creator);
priv->_creator = g_strdup(json_node_get_string(node));
} else {
g_warning("content.creator is missing from a m.room.create event");
}
if ((node = json_object_get_member(content_root, "m.federate")) != NULL) {
priv->_federate = json_node_get_boolean(node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_create_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_create_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomCreatePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
const gchar *state_key;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_create_get_instance_private(MATRIX_EVENT_ROOM_CREATE(matrix_event_base));
if (priv->_creator == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.create event without a creator key");
return;
}
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generater a m.root.create event with a non-empty state_key");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
json_object_set_string_member(content_root, "creator", priv->_creator);
json_object_set_boolean_member(content_root, "m.federate", priv->_federate);
MATRIX_EVENT_BASE_CLASS (matrix_event_room_create_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomCreate *
matrix_event_room_create_construct(GType object_type)
{
return (MatrixEventRoomCreate *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_create_new:
*
* Create a new #MatrixEventRoomCreate object.
*
* Returns: (transfer none): a new #MatrixEventRoomCreate object
*/
MatrixEventRoomCreate *
matrix_event_room_create_new(void)
{
return matrix_event_room_create_construct(MATRIX_EVENT_TYPE_ROOM_CREATE);
}
/**
* matrix_event_room_create_get_creator:
* @event: a #MatrixEventRoomCreate
*
* Get the creator of the room.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the creator of the room
*/
const gchar *
matrix_event_room_create_get_creator(MatrixEventRoomCreate *matrix_event_room_create)
{
MatrixEventRoomCreatePrivate *priv;
g_return_val_if_fail(matrix_event_room_create != NULL, NULL);
priv = matrix_event_room_create_get_instance_private(matrix_event_room_create);
return priv->_creator;
}
/**
* matrix_event_room_create_set_creator:
* @event: a #MatrixEventRoomCreate
* @creator: (transfer none) (nullable): the user ID of the rooms creator
*
* Set the creator of the room in @event.
*/
void
matrix_event_room_create_set_creator(MatrixEventRoomCreate *matrix_event_room_create, const gchar *creator)
{
MatrixEventRoomCreatePrivate *priv;
g_return_if_fail(matrix_event_room_create != NULL);
priv = matrix_event_room_create_get_instance_private(matrix_event_room_create);
if (g_strcmp0(creator, priv->_creator) != 0) {
g_free(priv->_creator);
priv->_creator = g_strdup(creator);
g_object_notify_by_pspec((GObject *)matrix_event_room_create, matrix_event_room_create_properties[PROP_CREATOR]);
}
}
/**
* matrix_event_room_create_get_federate:
* @event: a #MatrixEventRoomCreate
*
* Get the federation status of the room. If this function returns %TRUE, the room may be
* federated to other homeservers.
*
* Returns: the federation status of the room
*/
gboolean
matrix_event_room_create_get_federate(MatrixEventRoomCreate *matrix_event_room_create)
{
MatrixEventRoomCreatePrivate *priv;
g_return_val_if_fail(matrix_event_room_create != NULL, FALSE);
priv = matrix_event_room_create_get_instance_private(matrix_event_room_create);
return priv->_federate;
}
/**
* matrix_event_room_create_set_federate:
* @event: a #MatrixEventRoomCreate
* @federate: a federation status
*
* Set the federation status of the room. See matrix_event_room_create_get_federate() for
* more information.
*/
void
matrix_event_room_create_set_federate(MatrixEventRoomCreate *matrix_event_room_create, gboolean federate)
{
MatrixEventRoomCreatePrivate *priv;
g_return_if_fail(matrix_event_room_create != NULL);
priv = matrix_event_room_create_get_instance_private(matrix_event_room_create);
if (priv->_federate != federate) {
priv->_federate = federate;
g_object_notify_by_pspec((GObject *)matrix_event_room_create, matrix_event_room_create_properties[PROP_FEDERATE]);
}
}
static void
matrix_event_room_create_finalize(GObject *gobject)
{
MatrixEventRoomCreatePrivate *priv = matrix_event_room_create_get_instance_private(MATRIX_EVENT_ROOM_CREATE(gobject));
g_free(priv->_creator);
G_OBJECT_CLASS(matrix_event_room_create_parent_class)->finalize(gobject);
}
static void
matrix_event_room_create_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomCreate *matrix_event_room_create = MATRIX_EVENT_ROOM_CREATE(gobject);
switch (property_id) {
case PROP_CREATOR:
g_value_set_string(value, matrix_event_room_create_get_creator(matrix_event_room_create));
break;
case PROP_FEDERATE:
g_value_set_boolean(value, matrix_event_room_create_get_federate(matrix_event_room_create));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_create_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomCreate *matrix_event_room_create = MATRIX_EVENT_ROOM_CREATE(gobject);
switch (property_id) {
case PROP_CREATOR:
matrix_event_room_create_set_creator(matrix_event_room_create, g_value_get_string(value));
break;
case PROP_FEDERATE:
matrix_event_room_create_set_federate(matrix_event_room_create, g_value_get_boolean(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_create_class_init(MatrixEventRoomCreateClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_create_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_create_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_create_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_create_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_create_finalize;
/**
* MatrixEventRoomCreate:creator:
*
* The user_id of the room creator. This is set by the homeserver.
*/
matrix_event_room_create_properties[PROP_CREATOR] = g_param_spec_string(
"creator", "creator", "creator",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_CREATOR, matrix_event_room_create_properties[PROP_CREATOR]);
/**
* MatrixEventRoomCreate:federate:
*
* Whether users on other servers can join this room. Defaults to %TRUE if key does not exist.
*/
matrix_event_room_create_properties[PROP_FEDERATE] = g_param_spec_boolean(
"federate", "federate", "federate",
FALSE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_FEDERATE, matrix_event_room_create_properties[PROP_FEDERATE]);
}
static void
matrix_event_room_create_init(MatrixEventRoomCreate *matrix_event_room_create)
{
MatrixEventRoomCreatePrivate *priv = matrix_event_room_create_get_instance_private(matrix_event_room_create);
priv->_creator = NULL;
priv->_federate = FALSE;
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_CREATE_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_CREATE_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_CREATE (matrix_event_room_create_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomCreate, matrix_event_room_create, MATRIX_EVENT, ROOM_CREATE, MatrixEventState);
struct _MatrixEventRoomCreateClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomCreate *matrix_event_room_create_new (void);
MatrixEventRoomCreate *matrix_event_room_create_construct (GType object_type);
const gchar *matrix_event_room_create_get_creator (MatrixEventRoomCreate *event);
void matrix_event_room_create_set_creator (MatrixEventRoomCreate *event, const gchar *creator);
gboolean matrix_event_room_create_get_federate (MatrixEventRoomCreate *event);
void matrix_event_room_create_set_federate (MatrixEventRoomCreate *event, gboolean federate);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_CREATE_H__ */

View File

@@ -1,86 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.create event
*
* This is the first event in a room and cannot be changed. It acts as
* the root of all other events.
*/
public class Matrix.Event.RoomCreate : Matrix.Event.State {
/**
* The user_id of the room creator. This is set by the homeserver.
*/
public string? creator { get; set; default = null; }
/**
* Whether users on other servers can join this room. Defaults to
* true if key does not exist.
*/
public bool federate { get; set; default = false; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.create event is non-empty");
}
}
if ((node = content_root.get_member("creator")) != null) {
_creator = node.get_string();
} else {
warning("content.creator is missing from a m.room.create event");
}
if ((node = content_root.get_member("m.federate")) != null) {
_federate = node.get_boolean();
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_creator == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.create event without a creator key");
}
if (state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generater a m.root.create event with a non-empty state_key");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
content_root.set_string_member("creator", _creator);
content_root.set_boolean_member("m.federate", _federate);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,260 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-guest-access.h"
#include "utils.h"
/**
* SECTION:matrix-event-room-guest-access
* @short_description: event describing guest access to a room
*
* This is the default event handler for `m.room.guest_access` events.
*
* This event controls whether guest users are allowed to join rooms. If this event is absent,
* servers should act as if it is present and has the `guest_access` value set to `forbidden`.
*/
enum {
PROP_0,
PROP_GUEST_ACCESS,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_guest_access_properties[NUM_PROPERTIES];
typedef struct {
MatrixGuestAccess _guest_access;
} MatrixEventRoomGuestAccessPrivate;
/**
* MatrixEventRoomGuestAccess:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomGuestAccess, matrix_event_room_guest_access, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_guest_access_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomGuestAccessPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_guest_access_get_instance_private(MATRIX_EVENT_ROOM_GUEST_ACCESS(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
#if DEBUG
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key == 0)) {
g_warning("state_key of a m.room.guest_access is non-empty");
}
}
#endif
if ((node = json_object_get_member(content_root, "guest_access")) != NULL) {
GError *inner_error = NULL;
MatrixGuestAccess guest_access = _matrix_g_enum_nick_to_value(MATRIX_TYPE_GUEST_ACCESS, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
priv->_guest_access = MATRIX_GUEST_ACCESS_UNKNOWN;
#if DEBUG
g_warning("Unknown value '%s' in a m.room.guest_access event", json_node_get_string(node));
#endif
} else {
priv->_guest_access = guest_access;
}
} else {
g_warning("content.guest_access is missing from a m.room.guest_access event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_guest_access_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_guest_access_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomGuestAccessPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
const gchar *state_key;
gchar *guest_access;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_guest_access_get_instance_private(MATRIX_EVENT_ROOM_GUEST_ACCESS(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.guest_access event with a non-empty state key");
return;
}
if (priv->_guest_access == MATRIX_GUEST_ACCESS_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNKNOWN_VALUE,
"Won't generate a m.room.guest_access event with an unknown content.guest_access key");
return;
}
guest_access = _matrix_g_enum_to_string(MATRIX_TYPE_GUEST_ACCESS, priv->_guest_access, '_');
json_object_set_string_member(content_root, "guest_access", guest_access);
g_free(guest_access);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_guest_access_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomGuestAccess *
matrix_event_room_guest_access_construct(GType object_type)
{
return (MatrixEventRoomGuestAccess *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_guest_access_new:
*
* Create a new #MatrixEventRoomGuestAccess object.
*
* Returns: (transfer full): a new #MatrixEventRoomGuestAccess object
*/
MatrixEventRoomGuestAccess *
matrix_event_room_guest_access_new(void)
{
return matrix_event_room_guest_access_construct(MATRIX_EVENT_TYPE_ROOM_GUEST_ACCESS);
}
/**
* matrix_event_room_guest_access_get_guest_access:
* @event: a #MatrixEventRoomGuestAccess
*
* Get the guest access status of the room from @event.
*
* Returns: the guest access status
*/
MatrixGuestAccess
matrix_event_room_guest_access_get_guest_access(MatrixEventRoomGuestAccess *matrix_event_room_guest_access)
{
MatrixEventRoomGuestAccessPrivate *priv;
g_return_val_if_fail(matrix_event_room_guest_access != NULL, 0);
priv = matrix_event_room_guest_access_get_instance_private(matrix_event_room_guest_access);
return priv->_guest_access;
}
/**
* matrix_event_room_guest_access_set_guest_access:
* @event: a #MatrixEventRoomGuestAccess
* @guest_access: a #MatrixGuestAccess value
*
* Set the guest access status for the room in @event.
*/
void
matrix_event_room_guest_access_set_guest_access(MatrixEventRoomGuestAccess *matrix_event_room_guest_access, MatrixGuestAccess guest_access)
{
MatrixEventRoomGuestAccessPrivate *priv;
g_return_if_fail(matrix_event_room_guest_access != NULL);
priv = matrix_event_room_guest_access_get_instance_private(matrix_event_room_guest_access);
if (priv->_guest_access != guest_access) {
priv->_guest_access = guest_access;
g_object_notify_by_pspec((GObject *)matrix_event_room_guest_access, matrix_event_room_guest_access_properties[PROP_GUEST_ACCESS]);
}
}
static void
matrix_event_room_guest_access_finalize (GObject *gobject)
{
G_OBJECT_CLASS(matrix_event_room_guest_access_parent_class)->finalize(gobject);
}
static void
matrix_event_room_guest_access_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomGuestAccess *matrix_event_room_guest_access = MATRIX_EVENT_ROOM_GUEST_ACCESS(gobject);
switch (property_id) {
case PROP_GUEST_ACCESS:
g_value_set_enum(value, matrix_event_room_guest_access_get_guest_access(matrix_event_room_guest_access));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_guest_access_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec) {
MatrixEventRoomGuestAccess *matrix_event_room_guest_access = MATRIX_EVENT_ROOM_GUEST_ACCESS(gobject);
switch (property_id) {
case PROP_GUEST_ACCESS:
matrix_event_room_guest_access_set_guest_access(matrix_event_room_guest_access, g_value_get_enum(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_guest_access_class_init(MatrixEventRoomGuestAccessClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_guest_access_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_guest_access_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_guest_access_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_guest_access_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_guest_access_finalize;
/**
* MatrixEventRoomGuestAccess:guest-access:
*
* Whether guests can join the room.
*/
matrix_event_room_guest_access_properties[PROP_GUEST_ACCESS] = g_param_spec_enum(
"guest-access", "guest-access", "guest-access",
MATRIX_TYPE_GUEST_ACCESS, MATRIX_GUEST_ACCESS_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_GUEST_ACCESS, matrix_event_room_guest_access_properties[PROP_GUEST_ACCESS]);
}
static void
matrix_event_room_guest_access_init(MatrixEventRoomGuestAccess *matrix_event_room_guest_access)
{
MatrixEventRoomGuestAccessPrivate *priv = matrix_event_room_guest_access_get_instance_private(matrix_event_room_guest_access);
priv->_guest_access = MATRIX_GUEST_ACCESS_UNKNOWN;
}

View File

@@ -0,0 +1,42 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_GUEST_ACCESS_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_GUEST_ACCESS_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
# include "matrix-enumtypes.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_GUEST_ACCESS (matrix_event_room_guest_access_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomGuestAccess, matrix_event_room_guest_access, MATRIX_EVENT, ROOM_GUEST_ACCESS, MatrixEventState);
struct _MatrixEventRoomGuestAccessClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomGuestAccess *matrix_event_room_guest_access_new(void);
MatrixEventRoomGuestAccess *matrix_event_room_guest_access_construct(GType object_type);
MatrixGuestAccess matrix_event_room_guest_access_get_guest_access(MatrixEventRoomGuestAccess *event);
void matrix_event_room_guest_access_set_guest_access(MatrixEventRoomGuestAccess *event, MatrixGuestAccess guest_access);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_GUEST_ACCESS_H__ */

View File

@@ -1,94 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.guest_access event
*
* This event controls whether guest users are allowed to join
* rooms. If this event is absent, servers should act as if it is
* present and has the guest_access value `forbidden`.
*/
/**
* Class to hold a m.room.guest_access event
*/
public class Matrix.Event.RoomGuestAccess : Matrix.Event.State {
/**
* Whether guests can join the room.
*/
public GuestAccess guest_access { get; set; default = GuestAccess.UNKNOWN; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.guest_access is non-empty");
}
}
if ((node = content_root.get_member("guest_access")) != null) {
GuestAccess? rules = (GuestAccess?)_g_enum_nick_to_value(
typeof(GuestAccess), node.get_string());
if (rules != null) {
_guest_access = rules;
} else {
_guest_access = GuestAccess.UNKNOWN;
if (Config.DEBUG) {
warning("Unknown value '%s' in a m.room.guest_access event",
node.get_string());
}
}
} else {
warning("content.guest_access is missing from a m.room.guest_access event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.guest_access event with a non-empty state key");
}
if ((_guest_access == GuestAccess.UNKNOWN)) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.guest_access event with an unknown content.guest_access key");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
content_root.set_string_member(
"guest_access",
_g_enum_value_to_nick(typeof(GuestAccess), _guest_access));
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,262 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-history-visibility.h"
#include "utils.h"
/**
* SECTION:matrix-event-room-history-visibility
* @short_description: event to control history visibility to room members
*
* This is the default event handler for `m.room.history_visibility` events.
*
* This event controls whether a user can see the events that happened in a room from before
* they joined.
*/
enum {
PROP_0,
PROP_VISIBILITY,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_history_visibility_properties[NUM_PROPERTIES];
typedef struct {
MatrixHistoryVisibility _visibility;
} MatrixEventRoomHistoryVisibilityPrivate;
/**
* MatrixEventRoomHistoryVisibility:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomHistoryVisibility, matrix_event_room_history_visibility, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_history_visibility_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomHistoryVisibilityPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_history_visibility_get_instance_private(MATRIX_EVENT_ROOM_HISTORY_VISIBILITY(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
#ifdef DEBUG
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key == 0)) {
g_warning("state_key of a m.room.history_visibility event is non-empty");
}
}
#endif
if ((node = json_object_get_member(content_root, "history_visibility")) != NULL) {
GError *inner_error = NULL;
MatrixHistoryVisibility visibility = _matrix_g_enum_nick_to_value(MATRIX_TYPE_HISTORY_VISIBILITY, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
priv->_visibility = MATRIX_HISTORY_VISIBILITY_UNKNOWN;
#ifdef DEBUG
g_warning("Unknown history_visibility value %s", json_node_get_string(node));
#endif
} else {
priv->_visibility = visibility;
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_history_visibility_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_history_visibility_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomHistoryVisibilityPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
const gchar *state_key;
gchar *visibility_str;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_history_visibility_get_instance_private(MATRIX_EVENT_ROOM_HISTORY_VISIBILITY(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.history_visibility event with a non-empty state key");
return;
}
if (priv->_visibility == MATRIX_HISTORY_VISIBILITY_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNKNOWN_VALUE,
"Won't send m.room.history_visibility event with unknown visibility value");
return;
}
visibility_str = _matrix_g_enum_to_string(MATRIX_TYPE_HISTORY_VISIBILITY, priv->_visibility, '_');
json_object_set_string_member(content_root, "history_visibility", visibility_str);
g_free(visibility_str);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_history_visibility_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomHistoryVisibility *
matrix_event_room_history_visibility_construct(GType object_type)
{
return (MatrixEventRoomHistoryVisibility *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_history_visibility_new:
*
* Create a new #MatrixEventRoomHistoryVisibility object.
*
* Returns: (transfer full): a new #MatrixEventRoomHistoryVisibility object
*/
MatrixEventRoomHistoryVisibility *
matrix_event_room_history_visibility_new(void)
{
return matrix_event_room_history_visibility_construct(MATRIX_EVENT_TYPE_ROOM_HISTORY_VISIBILITY);
}
/**
* matrix_event_room_history_visibility_get_visibility:
* @event: a #MatrixEventRoomHistoryVisibility
*
* Get the history visibility status of the room.
*
* Returns: a #MatrixHistoryVisibility value
*/
MatrixHistoryVisibility
matrix_event_room_history_visibility_get_visibility(MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility)
{
MatrixEventRoomHistoryVisibilityPrivate *priv;
g_return_val_if_fail(matrix_event_room_history_visibility != NULL, 0);
priv = matrix_event_room_history_visibility_get_instance_private(matrix_event_room_history_visibility);
return priv->_visibility;
}
/**
* matrix_event_room_history_visibility_set_visibility:
* @event: a #MatrixEventRoomHistoryVisibility
* @history_visibility: a #MatrixHistoryVisibility value
*
* Set the history visibility in @event.
*/
void
matrix_event_room_history_visibility_set_visibility(MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility, MatrixHistoryVisibility visibility)
{
MatrixEventRoomHistoryVisibilityPrivate *priv;
g_return_if_fail(matrix_event_room_history_visibility != NULL);
priv = matrix_event_room_history_visibility_get_instance_private(matrix_event_room_history_visibility);
if (priv->_visibility != visibility) {
priv->_visibility = visibility;
g_object_notify_by_pspec((GObject *)matrix_event_room_history_visibility, matrix_event_room_history_visibility_properties[PROP_VISIBILITY]);
}
}
static void
matrix_event_room_history_visibility_finalize(GObject *gobject) {
G_OBJECT_CLASS(matrix_event_room_history_visibility_parent_class)->finalize(gobject);
}
static void
matrix_event_room_history_visibility_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility = MATRIX_EVENT_ROOM_HISTORY_VISIBILITY(gobject);
switch (property_id) {
case PROP_VISIBILITY:
g_value_set_enum(value, matrix_event_room_history_visibility_get_visibility(matrix_event_room_history_visibility));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_history_visibility_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility = MATRIX_EVENT_ROOM_HISTORY_VISIBILITY(gobject);
switch (property_id) {
case PROP_VISIBILITY:
matrix_event_room_history_visibility_set_visibility(matrix_event_room_history_visibility, g_value_get_enum(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_history_visibility_class_init(MatrixEventRoomHistoryVisibilityClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_history_visibility_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_history_visibility_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_history_visibility_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_history_visibility_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_history_visibility_finalize;
/**
* MatrixEventRoomHistoryVisibiliy:visibility:
*
* Who can see the room history.
*/
matrix_event_room_history_visibility_properties[PROP_VISIBILITY] = g_param_spec_enum(
"visibility", "visibility", "visibility",
MATRIX_TYPE_HISTORY_VISIBILITY, MATRIX_HISTORY_VISIBILITY_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_VISIBILITY, matrix_event_room_history_visibility_properties[PROP_VISIBILITY]);
}
static void
matrix_event_room_history_visibility_init(MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility)
{
MatrixEventRoomHistoryVisibilityPrivate *priv = matrix_event_room_history_visibility_get_instance_private(matrix_event_room_history_visibility);
priv->_visibility = MATRIX_HISTORY_VISIBILITY_UNKNOWN;
}

View File

@@ -0,0 +1,42 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_HISTORY_VISIBILITY_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_HISTORY_VISIBILITY_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
# include "matrix-enumtypes.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_HISTORY_VISIBILITY (matrix_event_room_history_visibility_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomHistoryVisibility, matrix_event_room_history_visibility, MATRIX_EVENT, ROOM_HISTORY_VISIBILITY, MatrixEventState);
struct _MatrixEventRoomHistoryVisibilityClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility_new(void);
MatrixEventRoomHistoryVisibility *matrix_event_room_history_visibility_construct(GType object_type);
MatrixHistoryVisibility matrix_event_room_history_visibility_get_visibility(MatrixEventRoomHistoryVisibility *event);
void matrix_event_room_history_visibility_set_visibility(MatrixEventRoomHistoryVisibility *event, MatrixHistoryVisibility history_visibility);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_HISTORY_VISIBILITY_H__ */

View File

@@ -1,92 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.history_visibility event.
*
* This event controls whether a user can see the events that happened
* in a room from before they joined.
*/
public class Matrix.Event.RoomHistoryVisibility : Matrix.Event.State {
/**
* Who can see the room history.
*/
public Matrix.HistoryVisibility visibility {
get; set;
default = Matrix.HistoryVisibility.UNKNOWN;
}
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.history_visibility event is non-empty");
}
}
if ((node = content_root.get_member("history_visibility")) != null) {
Matrix.HistoryVisibility? vis = (Matrix.HistoryVisibility?)_g_enum_nick_to_value(
typeof(Matrix.HistoryVisibility),
node.get_string());
if (vis != null) {
_visibility = vis;
} else {
_visibility = Matrix.HistoryVisibility.UNKNOWN;
if (Config.DEBUG) {
warning("Unknown history_visibility value %s", node.get_string());
}
}
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.history_visibility event with a non-empty state key");
}
if (visibility == Matrix.HistoryVisibility.UNKNOWN) {
throw new Matrix.Error.UNKNOWN_VALUE(
"Won't send m.room.history_visibility event with unknown visibility value");
}
content_root.set_string_member("history_visibility",
_g_enum_value_to_nick(
typeof(Matrix.HistoryVisibility),
visibility));
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,267 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-join-rules.h"
#include "utils.h"
/**
* SECTION:matrix-event-room-join-rules
* @short_description: event to hold the join rules for a room
*
* This is the default event handler for `m.room.join_rules` events.
*
* A room may be `public` meaning anyone can join the room without any prior action.
* Alternatively, it can be `invite` meaning that a user who wishes to join the room must
* first receive an invite to the room from someone already inside of the room. Currently,
* `knock` and `private` are reserved keywords which are not implemented.
*/
enum {
PROP_0,
PROP_JOIN_RULES,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_join_rules_properties[NUM_PROPERTIES];
typedef struct {
MatrixJoinRules _join_rules;
} MatrixEventRoomJoinRulesPrivate;
/**
* MatrixEventRoomJoinRules:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomJoinRules, matrix_event_room_join_rules, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_join_rules_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomJoinRulesPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_join_rules_get_instance_private(MATRIX_EVENT_ROOM_JOIN_RULES(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
#ifdef DEBUG
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key != 0)) {
g_warning("state_key of a m.room.join_rules is non-empty");
}
}
#endif
if ((node = json_object_get_member(content_root, "join_rule")) != NULL) {
GError *inner_error = NULL;
MatrixJoinRules join_rules = _matrix_g_enum_nick_to_value(MATRIX_TYPE_JOIN_RULES, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
priv->_join_rules = MATRIX_JOIN_RULES_UNKNOWN;
#ifdef DEBUG
g_warning("Unknown value %s in a m.room.join_rules event", json_node_get_string(node));
#endif
} else {
priv->_join_rules = join_rules;
}
} else {
priv->_join_rules = MATRIX_JOIN_RULES_UNKNOWN;
g_warning("content.join_rules is missing from a m.room.join_rules event.");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_join_rules_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_join_rules_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomJoinRulesPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
const gchar *state_key;
gchar *join_rules;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_join_rules_get_instance_private(MATRIX_EVENT_ROOM_JOIN_RULES(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.join_rules event with a non-empty state_key");
return;
}
if (priv->_join_rules == MATRIX_JOIN_RULES_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNKNOWN_VALUE,
"Won't send a m.room.join_rules event with an unknown rule");
return;
}
join_rules = _matrix_g_enum_to_string(MATRIX_TYPE_JOIN_RULES, priv->_join_rules, '_');
json_object_set_string_member(content_root, "join_rule", join_rules);
g_free(join_rules);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_join_rules_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomJoinRules *
matrix_event_room_join_rules_construct(GType object_type)
{
return (MatrixEventRoomJoinRules *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_join_rules_new:
*
* Create a new #MatrixEventRoomJoinRules object.
*
* Returns: (transfer full): a new #MatrixEventRoomJoinRules object
*/
MatrixEventRoomJoinRules *
matrix_event_room_join_rules_new(void) {
return matrix_event_room_join_rules_construct(MATRIX_EVENT_TYPE_ROOM_JOIN_RULES);
}
/**
* matrix_event_room_join_rules_get_join_rules:
* @event: a #MatrixEventRoomJoinRules
*
* Get the join rules for the room in @event.
*
* Returns: a #MatrixJoinRules value
*/
MatrixJoinRules
matrix_event_room_join_rules_get_join_rules(MatrixEventRoomJoinRules *matrix_event_room_join_rules)
{
MatrixEventRoomJoinRulesPrivate *priv;
g_return_val_if_fail(matrix_event_room_join_rules != NULL, 0);
priv = matrix_event_room_join_rules_get_instance_private(matrix_event_room_join_rules);
return priv->_join_rules;
}
/**
* matrix_event_room_join_rules_set_join_rules:
* @event: a #MatrixEventRoomJoinRules
* @join_rules: a #MatrixJoinRules value
*
* Set the join rules for the room in @event.
*/
void
matrix_event_room_join_rules_set_join_rules(MatrixEventRoomJoinRules *matrix_event_room_join_rules, MatrixJoinRules join_rules)
{
MatrixEventRoomJoinRulesPrivate *priv;
g_return_if_fail(matrix_event_room_join_rules != NULL);
priv = matrix_event_room_join_rules_get_instance_private(matrix_event_room_join_rules);
if (priv->_join_rules != join_rules) {
priv->_join_rules = join_rules;
g_object_notify_by_pspec((GObject *)matrix_event_room_join_rules, matrix_event_room_join_rules_properties[PROP_JOIN_RULES]);
}
}
static void
matrix_event_room_join_rules_finalize(GObject *gobject)
{
G_OBJECT_CLASS(matrix_event_room_join_rules_parent_class)->finalize(gobject);
}
static void
matrix_event_room_join_rules_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomJoinRules *matrix_event_room_join_rules = MATRIX_EVENT_ROOM_JOIN_RULES(gobject);
switch (property_id) {
case PROP_JOIN_RULES:
g_value_set_enum(value, matrix_event_room_join_rules_get_join_rules(matrix_event_room_join_rules));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_join_rules_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomJoinRules *matrix_event_room_join_rules = MATRIX_EVENT_ROOM_JOIN_RULES(gobject);
switch (property_id) {
case PROP_JOIN_RULES:
matrix_event_room_join_rules_set_join_rules(matrix_event_room_join_rules, g_value_get_enum(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_join_rules_class_init(MatrixEventRoomJoinRulesClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_join_rules_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_join_rules_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_join_rules_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_join_rules_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_join_rules_finalize;
/**
* MatrixEventRoomJoinRules:join-rules:
*
* The join rules.
*/
matrix_event_room_join_rules_properties[PROP_JOIN_RULES] = g_param_spec_enum(
"join-rules", "join-rules", "join-rules",
MATRIX_TYPE_JOIN_RULES, MATRIX_JOIN_RULES_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_JOIN_RULES, matrix_event_room_join_rules_properties[PROP_JOIN_RULES]);
}
static void
matrix_event_room_join_rules_init(MatrixEventRoomJoinRules *matrix_event_room_join_rules)
{
MatrixEventRoomJoinRulesPrivate *priv = matrix_event_room_join_rules_get_instance_private(matrix_event_room_join_rules);
priv->_join_rules = MATRIX_JOIN_RULES_UNKNOWN;
}

View File

@@ -0,0 +1,42 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_JOIN_RULES_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_JOIN_RULES_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
# include "matrix-enumtypes.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_JOIN_RULES (matrix_event_room_join_rules_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomJoinRules, matrix_event_room_join_rules, MATRIX_EVENT, ROOM_JOIN_RULES, MatrixEventState);
struct _MatrixEventRoomJoinRulesClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomJoinRules *matrix_event_room_join_rules_new (void);
MatrixEventRoomJoinRules *matrix_event_room_join_rules_construct (GType object_type);
MatrixJoinRules matrix_event_room_join_rules_get_join_rules (MatrixEventRoomJoinRules *event);
void matrix_event_room_join_rules_set_join_rules (MatrixEventRoomJoinRules *event, MatrixJoinRules join_rules);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_JOIN_RULES_H__ */

View File

@@ -1,91 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.join_rules event.
*
* A room may be public meaning anyone can join the room without any
* prior action. Alternatively, it can be invite meaning that a user
* who wishes to join the room must first receive an invite to the
* room from someone already inside of the room. Currently, knock and
* private are reserved keywords which are not implemented.
*/
public class Matrix.Event.RoomJoinRules : Matrix.Event.State {
public JoinRules join_rules { get; set; default = JoinRules.UNKNOWN; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.join_rules is non-empty");
}
}
if ((node = content_root.get_member("join_rule")) != null) {
Matrix.JoinRules? rules = (Matrix.JoinRules)_g_enum_nick_to_value(
typeof(Matrix.JoinRules), node.get_string());
if (rules != null) {
_join_rules = rules;
} else {
_join_rules = Matrix.JoinRules.UNKNOWN;
if (Config.DEBUG) {
warning("Unknown value %s in a m.room.join_rules event",
node.get_string());
}
}
} else {
_join_rules = Matrix.JoinRules.UNKNOWN;
warning("content.join_rules is missing from a m.room.join_rules event.");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object().
get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.join_rules event with a non-empty state_key");
}
if (_join_rules == Matrix.JoinRules.UNKNOWN) {
throw new Matrix.Error.INCOMPLETE(
"Won't send a m.room.join_rules event with an unknown rule");
}
content_root.set_string_member(
"join_rule",
_g_enum_value_to_nick(typeof(Matrix.JoinRules), _join_rules));
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,999 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-member.h"
#include "config.h"
#include "utils.h"
/**
* SECTION:matrix-event-room-member
* @short_description: event representing room membership
*
* This is the default event handler for `m.room.member` events.
*
* Adjusts the membership state for a user in a room. It is preferable to use the membership
* APIs like matrix_api_invite_user() when performing membership actions rather than adjusting
* the state directly as there are a restricted set of valid transformations. For example,
* user A cannot force user B to join a room, and trying to force this state change directly
* will fail.
*
* The following membership states are specified:
*
* * `invite` - The user has been invited to join a room, but has not yet joined it. They may
* not participate in the room until they join.
* * `join` - The user has joined the room (possibly after accepting an invite), and may
* participate in it.
* * `leave` - The user was once joined to the room, but has since left (possibly by choice,
* or possibly by being kicked).
* * `ban` - The user has been banned from the room, and is no longer allowed to join it until
* they are un-banned from the room (by having their membership state set to a value other
* than ban).
* * `knock` - This is a reserved word, which currently has no meaning.
*
* See also #MatrixRoomMembership for more information.
*
* The MatrixEventRoomMember:third-party-invite property will be set if this invite is an
* invite event and is the successor of an `m.room.third_party_invite` event, and absent
* otherwise.
*
* This event may also include an `invite_room_state` key outside the content key. If present,
* this contains an array of stripped state events. These events provide information on a few
* select state events such as the room name.
*/
enum {
PROP_0,
PROP_MEMBERSHIP,
PROP_AVATAR_URL,
PROP_DISPLAY_NAME,
PROP_TPI_DISPLAY_NAME,
PROP_TPI_SIGNED_MXID,
PROP_TPI_SIGNED_TOKEN,
PROP_TPI_SIGNATURE,
PROP_USER_ID,
NUM_PROPERTIES
};
static GParamSpec* matrix_event_room_member_properties[NUM_PROPERTIES];
typedef struct {
MatrixRoomMembership _membership;
gchar* _avatar_url;
gchar* _display_name;
gchar* _tpi_display_name;
gchar* _tpi_signed_mxid;
gchar* _tpi_signed_token;
JsonNode* _tpi_signature;
MatrixEventState** _invite_room_state;
gint _invite_room_state_len;
gint __invite_room_state_size_;
} MatrixEventRoomMemberPrivate;
/**
* MatrixEventRoomMember:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomMember, matrix_event_room_member, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_member_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomMemberPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_member_get_instance_private(MATRIX_EVENT_ROOM_MEMBER(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
// Even though the state_key is handled by the parent class,
// in this event type this actually means the sender
if ((node = json_object_get_member(root, "state_key")) != NULL) {
matrix_event_state_set_state_key(MATRIX_EVENT_STATE(matrix_event_base), json_node_get_string(node));
} else {
g_warning("state_key is missing from a m.room.member event");
}
if ((node = json_object_get_member(content_root, "membership")) != NULL) {
MatrixRoomMembership membership;
membership = _matrix_g_enum_nick_to_value(MATRIX_TYPE_ROOM_MEMBERSHIP, json_node_get_string(node), &inner_error);
if (inner_error != NULL) {
g_clear_error(&inner_error);
priv->_membership = MATRIX_ROOM_MEMBERSHIP_UNKNOWN;
if (DEBUG) {
g_warning("Unknown membership value %s", json_node_get_string(node));
}
} else {
priv->_membership = membership;
}
} else if (DEBUG) {
g_warning("membership key is missing from the m.room.member event");
}
if ((node = json_object_get_member(content_root, "avatar_url")) != NULL) {
g_free(priv->_avatar_url);
priv->_avatar_url = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(content_root, "displayname")) != NULL) {
g_free(priv->_display_name);
priv->_display_name = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(content_root, "third_party_invite")) != NULL) {
JsonObject *tpi_root = json_node_get_object(node);
if ((node = json_object_get_member(tpi_root, "display_name")) != NULL) {
g_free(priv->_tpi_display_name);
priv->_tpi_display_name = g_strdup(json_node_get_string(node));
} else {
g_warning("content.third_party_invite.display_name is missing from a m.room.member event");
}
if ((node = json_object_get_member(tpi_root, "signed")) != NULL) {
JsonObject *signed_root = json_node_get_object(node);
if ((node = json_object_get_member(signed_root, "mxid")) != NULL) {
g_free(priv->_tpi_signed_mxid);
priv->_tpi_signed_mxid = g_strdup(json_node_get_string(node));
} else {
g_warning("content.third_party_invit.signed.mxid is missing from a m.room.member event");
}
if ((node = json_object_get_member(signed_root, "token")) != NULL) {
g_free(priv->_tpi_signed_token);
priv->_tpi_signed_token = g_strdup(json_node_get_string(node));
} else {
g_warning("content.third_party_invite.signed.token is missing from a m.room.member event");
}
if ((node = json_object_get_member(signed_root, "signatures")) != NULL) {
json_node_unref(priv->_tpi_signature);
priv->_tpi_signature = json_node_ref(node);
} else {
g_warning("content.third_party_invite.signed.signatures is missing from a m.room.member event");
}
} else {
g_warning("content.third_party_invite.signed is missing from a m.room.member event");
}
}
if ((node = json_object_get_member(root, "invite_room_state")) != NULL) {
JsonArray *events = json_node_get_array(node);
gint events_len;
if ((events_len = json_array_get_length(events)) > 0) {
for (gint i = 0; i < priv->_invite_room_state_len; i++) {
g_object_unref(priv->_invite_room_state[i]);
}
g_free(priv->_invite_room_state);
priv->_invite_room_state_len = events_len;
priv->_invite_room_state = g_new(MatrixEventState *, events_len);
for (gint i = 0; i < events_len; i++) {
JsonNode *member_node = json_array_get_element(events, i);
MatrixEventState *event;
GError *error = NULL;
event = (MatrixEventState *)matrix_event_base_new_from_json(NULL, member_node, &error);
if (error == NULL) {
priv->_invite_room_state[i] = g_object_ref(event);
}
g_object_unref(event);
}
}
}
// Chain up
MATRIX_EVENT_BASE_CLASS(matrix_event_room_member_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_room_member_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomMemberPrivate *priv;
const gchar *state_key;
gchar *membership;
JsonObject *root;
JsonObject *content_root;
JsonObject *tpi_root;
JsonObject *tpi_signed_root;
JsonNode *content_node;
GError *inner_error = NULL;
priv = matrix_event_room_member_get_instance_private(MATRIX_EVENT_ROOM_MEMBER(matrix_event_base));
if (priv->_membership == MATRIX_ROOM_MEMBERSHIP_UNKNOWN) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_UNKNOWN_VALUE,
"Unknown membership value cannot be added to a room member event");
return;
}
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.member event with an empty state_key");
return;
}
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
membership = _matrix_g_enum_to_string(MATRIX_TYPE_ROOM_MEMBERSHIP, priv->_membership, '_');
if (membership != NULL) {
json_object_set_string_member(content_root, "membership", membership);
g_free(membership);
} else {
g_critical("Won't generate a m.room.member event with an unknown membership");
}
if (priv->_avatar_url != NULL) {
json_object_set_string_member(content_root, "avatar_url", priv->_avatar_url);
}
if (priv->_display_name != NULL) {
json_object_set_string_member(content_root, "displayname", priv->_display_name);
}
tpi_root = json_object_new();
if (priv->_tpi_display_name != NULL) {
json_object_set_string_member(tpi_root, "display_name", priv->_tpi_display_name);
}
tpi_signed_root = json_object_new();
if (priv->_tpi_signed_mxid != NULL) {
json_object_set_string_member(tpi_signed_root, "mxid", priv->_tpi_signed_mxid);
}
if (priv->_tpi_signed_token != NULL) {
json_object_set_string_member(tpi_signed_root, "token", priv->_tpi_signed_token);
}
if (priv->_tpi_signature != NULL) {
json_object_set_member(tpi_signed_root, "signature", priv->_tpi_signature);
}
if ((json_object_get_size(tpi_signed_root) != 3) &&
(json_object_get_size(tpi_signed_root) != 0)) {
g_warning("3rd party invite data is not filled; ignoring");
tpi_signed_root = (json_object_unref(tpi_signed_root), NULL);
}
if ((tpi_signed_root != NULL) && (priv->_tpi_display_name != NULL)) {
JsonNode *tpi_signed_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(tpi_signed_node, tpi_signed_root);
json_object_set_member(tpi_root, "signed", tpi_signed_node);
}
if (json_object_get_size(tpi_root) == 2) {
JsonNode *tpi_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(tpi_node, tpi_root);
json_object_set_member(content_root, "third_party_invite", tpi_node);
} else if (json_object_get_size(tpi_root) != 0) {
tpi_root = (json_object_unref(tpi_root), NULL);
g_warning("3rd party invite data is incomplete; ignoring");
}
if (priv->_invite_room_state != NULL) {
JsonArray *state_ary = json_array_new();
for (gint i = 0; i < priv->_invite_room_state_len; i++) {
JsonNode *state_node = matrix_event_state_get_stripped_node(priv->_invite_room_state[i]);
json_array_add_element(state_ary, state_node);
}
if (json_array_get_length(state_ary) > 0) {
JsonNode *state_node = json_node_new(JSON_TYPE_ARRAY);
json_node_set_array(state_node, state_ary);
json_object_set_member(root, "invite_room_state", state_node);
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_member_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
MatrixEventRoomMember *
matrix_event_room_member_construct(GType object_type)
{
return (MatrixEventRoomMember *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_member_new:
*
* Create a new #MatrixEventRoomMember object.
*
* Returns: (transfer full): a new #MatrixEventRoomMember object
*/
MatrixEventRoomMember *
matrix_event_room_member_new(void)
{
return matrix_event_room_member_construct(MATRIX_EVENT_TYPE_ROOM_MEMBER);
}
/**
* matrix_event_room_member_get_membership:
* @event: a #MatrixEventRoomMember
*
* Get the membership status from @event.
*
* Returns: a #MatrixRoomMembership value
*/
MatrixRoomMembership
matrix_event_room_member_get_membership(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, 0);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_membership;
}
/**
* matrix_event_room_member_set_membership:
* @event: a #MatrixEventRoomMember
* @membership: a #MatrixRoomMembership value
*
* Set the membership value in @event.
*/
void
matrix_event_room_member_set_membership(MatrixEventRoomMember *matrix_event_room_member, MatrixRoomMembership membership)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (priv->_membership != membership) {
priv->_membership = membership;
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_MEMBERSHIP]);
}
}
/**
* matrix_event_room_member_get_avatar_url:
* @event: a #MatrixEventRoomMember
*
* Get the avatar URL from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): an avatar URL
*/
const gchar *
matrix_event_room_member_get_avatar_url(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_avatar_url;
}
/**
* matrix_event_room_member_set_avatar_url:
* @event: a #MatrixEventRoomMember
* @avatar_url: (transfer none) (nullable): the avatar URL for @event
*
* Set the avatar URL in @event.
*/
void
matrix_event_room_member_set_avatar_url(MatrixEventRoomMember *matrix_event_room_member, const gchar *avatar_url)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (g_strcmp0(avatar_url, priv->_avatar_url) != 0) {
g_free(priv->_avatar_url);
priv->_avatar_url = g_strdup(avatar_url);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_AVATAR_URL]);
}
}
/**
* matrix_event_room_member_get_display_name:
* @event: a #MatrixEventRoomMember
*
* Get the display name from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a display name
*/
const gchar *
matrix_event_room_member_get_display_name(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_display_name;
}
/**
* matrix_event_room_member_set_display_name:
* @event: a #MatrixEventRoomMember
* @display_name: (transfer none) (nullable): a display name
*
* Set the display name in @event.
*/
void
matrix_event_room_member_set_display_name(MatrixEventRoomMember *matrix_event_room_member, const gchar *display_name)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (g_strcmp0(display_name, priv->_display_name) != 0) {
g_free(priv->_display_name);
priv->_display_name = g_strdup(display_name);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_DISPLAY_NAME]);
}
}
/**
* matrix_event_room_member_get_tpi_display_name:
* @event: a #MatrixEventRoomMember
*
* Get the 3rd party display name from @event. It will be %NULL if the member was not invited
* by a 3rd party ID.
*
* The returned value is owned by @event, and should not be freed.
*
* Returns: (transfer none) (nullable): a 3rd party display name
*/
const gchar *
matrix_event_room_member_get_tpi_display_name(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_tpi_display_name;
}
/**
* matrix_event_room_member_set_tpi_display_name:
* @event: a #MatrixEventRoomMember
* @tpi_display_name: a 3rd party display name
*
* Set the 3rd party display name in @event.
*/
void
matrix_event_room_member_set_tpi_display_name(MatrixEventRoomMember *matrix_event_room_member, const gchar *tpi_display_name)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (g_strcmp0(tpi_display_name, priv->_tpi_display_name) != 0) {
g_free(priv->_tpi_display_name);
priv->_tpi_display_name = g_strdup(tpi_display_name);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_DISPLAY_NAME]);
}
}
/**
* matrix_event_room_member_get_tpi_signed_mxid:
* @event: a #MatrixEventRoomMember
*
* Get the signed 3rd party Matrix ID.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a 3rd party Matrix ID
*/
const gchar *
matrix_event_room_member_get_tpi_signed_mxid(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_tpi_signed_mxid;
}
/**
* matrix_event_room_member_set_tpi_signed_mxid:
* @event: a #MatrixEventRoomMember
* @tpi_signed_mxid: a 3rd party signed Matrix ID
*
* Set the signed 3rd party Matrix ID.
*/
void
matrix_event_room_member_set_tpi_signed_mxid(MatrixEventRoomMember *matrix_event_room_member, const gchar *tpi_signed_mxid)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (g_strcmp0(tpi_signed_mxid, priv->_tpi_signed_mxid) != 0) {
g_free(priv->_tpi_signed_mxid);
priv->_tpi_signed_mxid = g_strdup(tpi_signed_mxid);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_SIGNED_MXID]);
}
}
/**
* matrix_event_room_member_get_tpi_signed_token:
* @event: a #MatrixEventRoomMember
*
* Get the signed 3rd party token.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a signed 3rd party token
*/
const gchar *
matrix_event_room_member_get_tpi_signed_token(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_tpi_signed_token;
}
/**
* matrix_event_room_member_set_tpi_signed_token:
* @event: a #MatrixEventRoomMember
* @tpi_signed_token: a signed 3rd party token
*
* Set the signed 3rd party token in @event.
*/
void
matrix_event_room_member_set_tpi_signed_token(MatrixEventRoomMember *matrix_event_room_member, const gchar *tpi_signed_token)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (g_strcmp0(tpi_signed_token, priv->_tpi_signed_token) != 0) {
g_free(priv->_tpi_signed_token);
priv->_tpi_signed_token = g_strdup(tpi_signed_token);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_SIGNED_TOKEN]);
}
}
/**
* matrix_event_room_member_get_tpi_signature:
* @event: a #MatrixEventRoomMember
*
* Get the 3rd party signature from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a 3rd party signature.
*/
JsonNode *
matrix_event_room_member_get_tpi_signature(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
return priv->_tpi_signature;
}
/**
* matrix_event_room_member_set_tpi_signature:
* @event: a #MatrixEventRoomMember
* @tpi_signature: a 3rd party signature
*
* Set the 3rd party signature in @event.
*/
void
matrix_event_room_member_set_tpi_signature(MatrixEventRoomMember *matrix_event_room_member, JsonNode *tpi_signature)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (priv->_tpi_signature != tpi_signature) {
json_node_unref(priv->_tpi_signature);
priv->_tpi_signature = json_node_ref(tpi_signature);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_TPI_SIGNATURE]);
}
}
/**
* matrix_event_room_member_get_invite_room_state:
* @event: a #MatrixEventRoomMember
* @n_invite_room_state: placeholder for the returned list, or %NULL to ignore
*
* Get the initial state events from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the list of initial state events
*/
MatrixEventState **
matrix_event_room_member_get_invite_room_state(MatrixEventRoomMember *matrix_event_room_member, int *n_invite_room_state)
{
MatrixEventRoomMemberPrivate *priv;
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
if (n_invite_room_state != NULL) {
*n_invite_room_state = priv->_invite_room_state_len;
}
return priv->_invite_room_state;
}
/**
* matrix_event_room_member_set_invite_room_state:
* @event: a #MatrixEventRoomMember
* @invite_room_state: a list of initial state events
* @n_invite_room_state: the length of @invite_room_state
*
* Set the initial state events in @event.
*/
void
matrix_event_room_member_set_invite_room_state(MatrixEventRoomMember *matrix_event_room_member, MatrixEventState **invite_room_state, int n_invite_room_state)
{
MatrixEventRoomMemberPrivate *priv;
g_return_if_fail(matrix_event_room_member != NULL);
priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
for (gint i = 0; i < priv->_invite_room_state_len; i++) {
g_object_unref(priv->_invite_room_state[i]);
}
g_free(priv->_invite_room_state);
priv->_invite_room_state = g_new(MatrixEventState *, n_invite_room_state);
for (gint i = 0; i < n_invite_room_state; i++) {
priv->_invite_room_state[i] = g_object_ref(invite_room_state[i]);
}
priv->_invite_room_state_len = n_invite_room_state;
}
/**
* matrix_event_room_member_get_user_id:
* @event: a #MatrixEventRoomMember
*
* Get the user ID from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a user ID
*/
const gchar *
matrix_event_room_member_get_user_id(MatrixEventRoomMember *matrix_event_room_member)
{
g_return_val_if_fail(matrix_event_room_member != NULL, NULL);
return matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_room_member));
}
/**
* matrix_event_room_member_set_user_id:
* @event: a #MatrixEventRoomMember
* @user_id: a Matrix user ID
*
* Set the user ID in @event.
*/
void
matrix_event_room_member_set_user_id(MatrixEventRoomMember *matrix_event_room_member, const gchar *user_id)
{
const gchar *state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_room_member));
if (g_strcmp0(state_key, user_id) != 0) {
matrix_event_state_set_state_key(MATRIX_EVENT_STATE(matrix_event_room_member), user_id);
g_object_notify_by_pspec((GObject *)matrix_event_room_member, matrix_event_room_member_properties[PROP_USER_ID]);
}
}
static void
matrix_event_room_member_finalize(GObject *gobject)
{
MatrixEventRoomMemberPrivate *priv = matrix_event_room_member_get_instance_private(MATRIX_EVENT_ROOM_MEMBER(gobject));
g_free(priv->_avatar_url);
g_free(priv->_display_name);
g_free(priv->_tpi_display_name);
g_free(priv->_tpi_signed_mxid);
g_free(priv->_tpi_signed_token);
json_node_unref(priv->_tpi_signature);
for (gint i = 0; i < priv->_invite_room_state_len; i++) {
g_object_unref(priv->_invite_room_state[i]);
}
g_free(priv->_invite_room_state);
G_OBJECT_CLASS(matrix_event_room_member_parent_class)->finalize(gobject);
}
static void
matrix_event_room_member_get_property(GObject *gobject, guint property_id, GValue* value, GParamSpec* pspec)
{
MatrixEventRoomMember *matrix_event_room_member = MATRIX_EVENT_ROOM_MEMBER(gobject);
switch (property_id) {
case PROP_MEMBERSHIP:
g_value_set_enum(value, matrix_event_room_member_get_membership(matrix_event_room_member));
break;
case PROP_AVATAR_URL:
g_value_set_string(value, matrix_event_room_member_get_avatar_url(matrix_event_room_member));
break;
case PROP_DISPLAY_NAME:
g_value_set_string(value, matrix_event_room_member_get_display_name(matrix_event_room_member));
break;
case PROP_TPI_DISPLAY_NAME:
g_value_set_string(value, matrix_event_room_member_get_tpi_display_name(matrix_event_room_member));
break;
case PROP_TPI_SIGNED_MXID:
g_value_set_string(value, matrix_event_room_member_get_tpi_signed_mxid(matrix_event_room_member));
break;
case PROP_TPI_SIGNED_TOKEN:
g_value_set_string(value, matrix_event_room_member_get_tpi_signed_token(matrix_event_room_member));
break;
case PROP_TPI_SIGNATURE:
g_value_set_boxed(value, matrix_event_room_member_get_tpi_signature(matrix_event_room_member));
break;
case PROP_USER_ID:
g_value_set_string(value, matrix_event_room_member_get_user_id(matrix_event_room_member));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_member_set_property(GObject *gobject, guint property_id, const GValue* value, GParamSpec* pspec)
{
MatrixEventRoomMember * matrix_event_room_member = MATRIX_EVENT_ROOM_MEMBER(gobject);
switch (property_id) {
case PROP_MEMBERSHIP:
matrix_event_room_member_set_membership (matrix_event_room_member, g_value_get_enum (value));
break;
case PROP_AVATAR_URL:
matrix_event_room_member_set_avatar_url (matrix_event_room_member, g_value_get_string (value));
break;
case PROP_DISPLAY_NAME:
matrix_event_room_member_set_display_name (matrix_event_room_member, g_value_get_string (value));
break;
case PROP_TPI_DISPLAY_NAME:
matrix_event_room_member_set_tpi_display_name (matrix_event_room_member, g_value_get_string (value));
break;
case PROP_TPI_SIGNED_MXID:
matrix_event_room_member_set_tpi_signed_mxid (matrix_event_room_member, g_value_get_string (value));
break;
case PROP_TPI_SIGNED_TOKEN:
matrix_event_room_member_set_tpi_signed_token (matrix_event_room_member, g_value_get_string (value));
break;
case PROP_TPI_SIGNATURE:
matrix_event_room_member_set_tpi_signature (matrix_event_room_member, g_value_get_boxed (value));
break;
case PROP_USER_ID:
matrix_event_room_member_set_user_id (matrix_event_room_member, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_member_class_init (MatrixEventRoomMemberClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_member_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_member_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_member_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_member_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_member_finalize;
/**
* MatrixEventRoomMember:membership:
*
* The membership state of the user.
*/
matrix_event_room_member_properties[PROP_MEMBERSHIP] = g_param_spec_enum(
"membership", "membership", "membership",
MATRIX_TYPE_ROOM_MEMBERSHIP, MATRIX_ROOM_MEMBERSHIP_UNKNOWN,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_MEMBERSHIP, matrix_event_room_member_properties[PROP_MEMBERSHIP]);
/**
* MatrixEventRoomMember:avatar-url:
*
* The avatar URL for this user, if any. This is added by the homeserver.
*/
matrix_event_room_member_properties[PROP_AVATAR_URL] = g_param_spec_string(
"avatar-url", "avatar-url", "avatar-url",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_AVATAR_URL, matrix_event_room_member_properties[PROP_AVATAR_URL]);
/**
* MatrixEventRoomMember:display-name:
*
* The display name for this user, if any. This is added by the homeserver.
*/
matrix_event_room_member_properties[PROP_DISPLAY_NAME] = g_param_spec_string(
"display-name", "display-name", "display-name",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DISPLAY_NAME, matrix_event_room_member_properties[PROP_DISPLAY_NAME]);
/**
* MatrixEventRoomMember:tpi-display-name:
*
* A name which can be displayed to represent the user instead of their third party identifier.
*/
matrix_event_room_member_properties[PROP_TPI_DISPLAY_NAME] = g_param_spec_string(
"tpi-display-name", "tpi-display-name", "tpi-display-name",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_DISPLAY_NAME, matrix_event_room_member_properties[PROP_TPI_DISPLAY_NAME]);
/**
* MatrixEventRoomMember:tpi-signed-mxid:
* The invited matrix user ID. Must be equal to the `user_id` property of the event.
*/
matrix_event_room_member_properties[PROP_TPI_SIGNED_MXID] = g_param_spec_string(
"tpi-signed-mxid", "tpi-signed-mxid", "tpi-signed-mxid",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_SIGNED_MXID, matrix_event_room_member_properties[PROP_TPI_SIGNED_MXID]);
/**
* MatrixEventRoomMember:tpi-signed-token:
*
* The token property of the containing third_party_invite object.
*/
matrix_event_room_member_properties[PROP_TPI_SIGNED_TOKEN] = g_param_spec_string(
"tpi-signed-token", "tpi-signed-token", "tpi-signed-token",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_SIGNED_TOKEN, matrix_event_room_member_properties[PROP_TPI_SIGNED_TOKEN]);
/**
* MatrixEventRoomMember:tpi-signature:
*
* A single signature from the verifying server, in the format specified by the Signing
* Events section of the server-server API.
*/
matrix_event_room_member_properties[PROP_TPI_SIGNATURE] = g_param_spec_boxed(
"tpi-signature", "tpi-signature", "tpi-signature",
JSON_TYPE_NODE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TPI_SIGNATURE, matrix_event_room_member_properties[PROP_TPI_SIGNATURE]);
/**
* MatrixEventRoomMember:user-id:
*
* The user ID whom this event relates to.
*/
matrix_event_room_member_properties[PROP_USER_ID] = g_param_spec_string(
"user-id", "user-id", "user-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_USER_ID, matrix_event_room_member_properties[PROP_USER_ID]);
}
static void
matrix_event_room_member_init(MatrixEventRoomMember *matrix_event_room_member)
{
MatrixEventRoomMemberPrivate *priv = matrix_event_room_member_get_instance_private(matrix_event_room_member);
priv->_membership = MATRIX_ROOM_MEMBERSHIP_UNKNOWN;
priv->_avatar_url = NULL;
priv->_display_name = NULL;
priv->_tpi_display_name = NULL;
priv->_tpi_signed_mxid = NULL;
priv->_tpi_signed_token = NULL;
priv->_tpi_signature = NULL;
matrix_event_room_member_set_user_id(matrix_event_room_member, NULL);
}

View File

@@ -0,0 +1,58 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRX_GLIB_SDK_EVENT_ROOM_MEMBER_H__
# define __MATRX_GLIB_SDK_EVENT_ROOM_MEMBER_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
# include "matrix-enumtypes.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_ROOM_MEMBER matrix_event_room_member_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomMember, matrix_event_room_member, MATRIX_EVENT, ROOM_MEMBER, MatrixEventState);
struct _MatrixEventRoomMemberClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomMember *matrix_event_room_member_new (void);
MatrixEventRoomMember *matrix_event_room_member_construct (GType object_type);
MatrixRoomMembership matrix_event_room_member_get_membership (MatrixEventRoomMember *event);
void matrix_event_room_member_set_membership (MatrixEventRoomMember *event, MatrixRoomMembership membership);
const gchar *matrix_event_room_member_get_avatar_url (MatrixEventRoomMember *event);
void matrix_event_room_member_set_avatar_url (MatrixEventRoomMember *event, const gchar *avatar_url);
const gchar *matrix_event_room_member_get_display_name (MatrixEventRoomMember *event);
void matrix_event_room_member_set_display_name (MatrixEventRoomMember *event, const gchar *display_name);
const gchar *matrix_event_room_member_get_tpi_display_name (MatrixEventRoomMember *event);
void matrix_event_room_member_set_tpi_display_name (MatrixEventRoomMember *event, const gchar *tpi_display_name);
const gchar *matrix_event_room_member_get_tpi_signed_mxid (MatrixEventRoomMember *event);
void matrix_event_room_member_set_tpi_signed_mxid (MatrixEventRoomMember *event, const gchar *tpi_signed_mxid);
const gchar *matrix_event_room_member_get_tpi_signed_token (MatrixEventRoomMember *event);
void matrix_event_room_member_set_tpi_signed_token (MatrixEventRoomMember *event, const gchar *tpi_signed_token);
JsonNode *matrix_event_room_member_get_tpi_signature (MatrixEventRoomMember *event);
void matrix_event_room_member_set_tpi_signature (MatrixEventRoomMember *event, JsonNode *tpi_signature);
MatrixEventState **matrix_event_room_member_get_invite_room_state (MatrixEventRoomMember *event, int *n_invite_room_state);
void matrix_event_room_member_set_invite_room_state (MatrixEventRoomMember *event, MatrixEventState **invite_room_state, int n_invite_room_state);
const gchar *matrix_event_room_member_get_user_id (MatrixEventRoomMember *event);
void matrix_event_room_member_set_user_id (MatrixEventRoomMember *event, const gchar *user_id);
G_END_DECLS
#endif /* __MATRX_GLIB_SDK_EVENT_ROOM_MEMBER_H__ */

View File

@@ -1,312 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class for representing a room membership events
*
* Adjusts the membership state for a user in a room. It is preferable
* to use the membership APIs (`/rooms/<room id>/invite` etc) when
* performing membership actions rather than adjusting the state
* directly as there are a restricted set of valid
* transformations. For example, user A cannot force user B to join a
* room, and trying to force this state change directly will
* fail.
*
* The following membership states are specified:
*
* - invite - The user has been invited to join a room, but has not
* yet joined it. They may not participate in the room until they
* join.
*
* - join - The user has joined the room (possibly after accepting an
* invite), and may participate in it.
*
* - leave - The user was once joined to the room, but has since left
* (possibly by choice, or possibly by being kicked).
*
* - ban - The user has been banned from the room, and is no longer
* allowed to join it until they are un-banned from the room (by
* having their membership state set to a value other than ban).
*
* - knock - This is a reserved word, which currently has no meaning.
*
* The third_party_invite property will be set if this invite is an
* invite event and is the successor of an m.room.third_party_invite
* event, and absent otherwise.
*
* This event may also include an invite_room_state key outside the
* content key. If present, this contains an array of stripped state
* events. These events provide information on a few select state
* events such as the room name.
*/
public class Matrix.Event.RoomMember : Matrix.Event.State {
/**
* The membership state of the user.
*/
public RoomMembership membership {
get; set;
default = RoomMembership.UNKNOWN;
}
/**
* The avatar URL for this user, if any. This is added by the
* homeserver.
*/
public string? avatar_url { get; set; default = null; }
/**
* The display name for this user, if any. This is added by the
* homeserver.
*/
public string? display_name { get; set; default = null; }
/**
* A name which can be displayed to represent the user instead of
* their third party identifier
*/
public string? tpi_display_name { get; set; default = null; }
/**
* The invited matrix user ID. Must be equal to the user_id
* property of the event.
*/
public string? tpi_signed_mxid { get; set; default = null; }
/**
* The token property of the containing third_party_invite object.
*/
public string? tpi_signed_token { get; set; default = null; }
/**
* A single signature from the verifying server, in the format
* specified by the Signing Events section of the server-server
* API.
*/
public Json.Node? tpi_signature { get; set; default = null; }
/**
* A subset of the state of the room at the time of the invite, if
* membership is invite.
*/
public Matrix.Event.State[] invite_room_state { get; set; }
/**
* The user ID whom this event relates to.
*/
public string? user_id {
get {
return _state_key;
}
set {
_state_key = value;
}
default = null;
}
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
Json.Object root = json_data.get_object();
Json.Object content_root = root.get_member("content").get_object();
Json.Node? node;
// Even though the state_key is handled by the parent class,
// in this event type this actually means the sender
if ((node = root.get_member("state_key")) != null) {
_state_key = node.get_string();
} else {
warning("state_key is missing from a m.room.member event");
}
if ((node = content_root.get_member("membership")) != null) {
Matrix.RoomMembership? mship = (Matrix.RoomMembership?)_g_enum_nick_to_value(
typeof(Matrix.RoomMembership),
node.get_string());
if (mship != null) {
_membership = mship;
}
} else if (Config.DEBUG) {
warning("membership key is missing from the m.room.member event");
}
if ((node = content_root.get_member("avatar_url")) != null) {
_avatar_url = node.get_string();
}
if ((node = content_root.get_member("displayname")) != null) {
_display_name = node.get_string();
}
if ((node = content_root.get_member("third_party_invite")) != null) {
var tpi_root = node.get_object();
if ((node = tpi_root.get_member("display_name")) != null) {
_tpi_display_name = node.get_string();
} else {
warning("content.third_party_invite.display_name is missing from a m.room.member event");
}
if ((node = tpi_root.get_member("signed")) != null) {
var signed_root = node.get_object();
if ((node = signed_root.get_member("mxid")) != null) {
tpi_signed_mxid = node.get_string();
} else {
warning("content.third_party_invit.signed.mxid is missing from a m.room.member event");
}
if ((node = signed_root.get_member("token")) != null) {
tpi_signed_token = node.get_string();
} else {
warning("content.third_party_invite.signed.token is missing from a m.room.member event");
}
if ((node = signed_root.get_member("signatures")) != null) {
tpi_signature = node;
} else {
warning("content.third_party_invite.signed.signatures is missing from a m.room.member event");
}
} else {
warning("content.third_party_invite.signed is missing from a m.room.member event");
}
}
if ((node = root.get_member("invite_room_state")) != null) {
var events = node.get_array();
if (events.get_length() > 0) {
_invite_room_state = new Matrix.Event.State[node.get_array().get_length()];
events.foreach_element((ary, idx, member_node) => {
try {
var evt = Matrix.Event.Base.new_from_json(
null, member_node);
_invite_room_state[idx] = (Matrix.Event.State)evt;
} catch (GLib.Error e) {}
});
}
}
// Chain up
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (membership == RoomMembership.UNKNOWN) {
throw new Matrix.Error.UNKNOWN_VALUE(
"Unknown membership value cannot be added to a room member event");
}
if (_state_key == "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.member event with an empty state_key");
}
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
string? mship;
mship = _g_enum_value_to_nick(typeof(Matrix.RoomMembership),
membership);
if (mship != null) {
content_root.set_string_member("membership", mship);
} else {
throw new Matrix.Error.UNKNOWN_VALUE(
"Won't generate a m.room.member event with an unknown membership");
}
if (avatar_url != null) {
content_root.set_string_member("avatar_url", avatar_url);
}
if (display_name != null) {
content_root.set_string_member("displayname", display_name);
}
var tpi_root = new Json.Object();
if (_tpi_display_name != null) {
tpi_root.set_string_member("display_name", tpi_display_name);
}
var tpi_signed_root = new Json.Object();
if (_tpi_signed_mxid != null) {
tpi_signed_root.set_string_member("mxid", tpi_signed_mxid);
}
if (_tpi_signed_token != null) {
tpi_signed_root.set_string_member("token", tpi_signed_token);
}
if (_tpi_signature != null) {
tpi_signed_root.set_member("signature", tpi_signature);
}
if ((tpi_signed_root.get_size() != 3)
&& (tpi_signed_root.get_size() != 0)) {
warning("3rd party invite data is not filled; ignoring");
tpi_signed_root = null;
}
if ((_tpi_display_name != null) && (tpi_signed_root.get_size() == 3)) {
var tpi_signed_node = new Json.Node(Json.NodeType.OBJECT);
tpi_signed_node.set_object(tpi_signed_root);
tpi_root.set_member("signed", tpi_signed_node);
}
if (tpi_root.get_size() == 2) {
var tpi_node = new Json.Node(Json.NodeType.OBJECT);
tpi_node.set_object(tpi_root);
content_root.set_member("third_party_invite", tpi_node);
} else if (tpi_root.get_size() != 0) {
warning("3rd party invite data is incomplete; ignoring");
}
if (_invite_room_state != null) {
var state_ary = new Json.Array();
foreach (var entry in _invite_room_state) {
var state_node = entry.get_stripped_node();
if (state_node != null) {
state_ary.add_element(state_node);
}
}
if (state_ary.get_length() > 0) {
var state_node = new Json.Node(Json.NodeType.ARRAY);
state_node.set_array(state_ary);
root.set_member("invite_room_state", state_node);
}
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,318 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-message-feedback.h"
#include "matrix-enumtypes.h"
/**
* SECTION:matrix-event-room-message-feedback
* @short_description: event to hold message feedbacks
*
* This is the default event handler for `m.room.message.feedback` events.
*
* Usage of this event is discouraged in favour of the receipts module. Most clients will not
* recognise this event.
*
* Feedback events are events sent to acknowledge a message in some way. There are two
* supported acknowledgements: `delivered` (sent when the event has been received) and `read`
* (sent when the event has been observed by the end-user). The `target_event_id` should
* reference the `m.room.message` event being acknowledged.
*/
enum {
PROP_0,
PROP_FEEDBACK_TYPE,
PROP_TARGET_EVENT_ID,
NUM_PROPERTIES
};
static GParamSpec* matrix_event_room_message_feedback_properties[NUM_PROPERTIES];
typedef struct {
gchar* _feedback_type;
gchar* _target_event_id;
} MatrixEventRoomMessageFeedbackPrivate;
/**
* MatrixEventRoomMessageFeedback:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomMessageFeedback, matrix_event_room_message_feedback, MATRIX_EVENT_TYPE_ROOM);
static void
matrix_event_room_message_feedback_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomMessageFeedbackPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_message_feedback_get_instance_private(MATRIX_EVENT_ROOM_MESSAGE_FEEDBACK(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "type")) != NULL) {
g_free(priv->_feedback_type);
priv->_feedback_type = g_strdup(json_node_get_string(node));
} else {
g_warning("content.type is missing from a m.room.message.feedback event");
}
if ((node = json_object_get_member(content_root, "target_event_id")) != NULL) {
g_free(priv->_target_event_id);
priv->_target_event_id = g_strdup(json_node_get_string(node));
} else {
g_warning("content.target_event_id is missing from a m.room.message.feedback event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_message_feedback_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_message_feedback_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomMessageFeedbackPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_message_feedback_get_instance_private(MATRIX_EVENT_ROOM_MESSAGE_FEEDBACK(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((priv->_feedback_type == NULL) || (priv->_target_event_id == NULL)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.message.feedback without all fields set");
return;
}
json_object_set_string_member(content_root, "type", priv->_feedback_type);
json_object_set_string_member(content_root, "target_event_id", priv->_target_event_id);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_message_feedback_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomMessageFeedback *
matrix_event_room_message_feedback_construct(GType object_type)
{
return (MatrixEventRoomMessageFeedback *)matrix_event_room_construct(object_type);
}
/**
* matrix_event_room_message_feedback_new:
*
* Create a new #MatrixEventRoomMessageFeedback object.
*
* Returns: (transfer full): a new #MatrixEventRoomMessageFeedback object
*/
MatrixEventRoomMessageFeedback *
matrix_event_room_message_feedback_new(void)
{
return matrix_event_room_message_feedback_construct(MATRIX_EVENT_TYPE_ROOM_MESSAGE_FEEDBACK);
}
/**
* matrix_event_room_message_feedback_get_feedback_type:
* @event: a #MatrixEventRoomMessageFeedback
*
* Get the feedback type from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the feedback type
*/
const gchar *
matrix_event_room_message_feedback_get_feedback_type(MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback)
{
MatrixEventRoomMessageFeedbackPrivate *priv;
g_return_val_if_fail(matrix_event_room_message_feedback != NULL, NULL);
priv = matrix_event_room_message_feedback_get_instance_private(matrix_event_room_message_feedback);
return priv->_feedback_type;
}
/**
* matrix_event_room_message_feedback_set_feedback_type:
* @event: a #MatrixEventRoomMessageFeedback
* @feedback_type: (transfer none) (nullable): a feedback type
*
* Set the feedback type in @event.
*/
void
matrix_event_room_message_feedback_set_feedback_type(MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback, const gchar *feedback_type)
{
MatrixEventRoomMessageFeedbackPrivate *priv;
g_return_if_fail(matrix_event_room_message_feedback != NULL);
priv = matrix_event_room_message_feedback_get_instance_private(matrix_event_room_message_feedback);
if (g_strcmp0(feedback_type, priv->_feedback_type) != 0) {
g_free(priv->_feedback_type);
priv->_feedback_type = g_strdup(feedback_type);
g_object_notify_by_pspec((GObject *)matrix_event_room_message_feedback, matrix_event_room_message_feedback_properties[PROP_FEEDBACK_TYPE]);
}
}
/**
* matrix_event_room_message_feedback_get_target_event_id:
* @event: a #MatrixEventRoomMessageFeedback
*
* Get the target events ID from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the ID of the target event
*/
const gchar *
matrix_event_room_message_feedback_get_target_event_id(MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback)
{
MatrixEventRoomMessageFeedbackPrivate *priv;
g_return_val_if_fail(matrix_event_room_message_feedback != NULL, NULL);
priv = matrix_event_room_message_feedback_get_instance_private(matrix_event_room_message_feedback);
return priv->_target_event_id;
}
/**
* matrix_event_room_message_feedback_set_target_event_id:
* @event: a #MatrixEventRoomMessageFeedback
* @target_event_id: the ID of the target event
*
* Set the ID of the target event in @event.
*/
void
matrix_event_room_message_feedback_set_target_event_id(MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback, const gchar *target_event_id)
{
MatrixEventRoomMessageFeedbackPrivate *priv;
g_return_if_fail(matrix_event_room_message_feedback != NULL);
priv = matrix_event_room_message_feedback_get_instance_private(matrix_event_room_message_feedback);
if (g_strcmp0(target_event_id, priv->_target_event_id) != 0) {
g_free(priv->_target_event_id);
priv->_target_event_id = g_strdup(target_event_id);
g_object_notify_by_pspec((GObject *)matrix_event_room_message_feedback, matrix_event_room_message_feedback_properties[PROP_TARGET_EVENT_ID]);
}
}
static void
matrix_event_room_message_feedback_finalize(GObject *gobject)
{
MatrixEventRoomMessageFeedbackPrivate *priv = matrix_event_room_message_feedback_get_instance_private(MATRIX_EVENT_ROOM_MESSAGE_FEEDBACK(gobject));
g_free(priv->_feedback_type);
g_free(priv->_target_event_id);
G_OBJECT_CLASS(matrix_event_room_message_feedback_parent_class)->finalize(gobject);
}
static void
matrix_event_room_message_feedback_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback = MATRIX_EVENT_ROOM_MESSAGE_FEEDBACK(gobject);
switch (property_id) {
case PROP_FEEDBACK_TYPE:
g_value_set_string(value, matrix_event_room_message_feedback_get_feedback_type(matrix_event_room_message_feedback));
break;
case PROP_TARGET_EVENT_ID:
g_value_set_string(value, matrix_event_room_message_feedback_get_target_event_id(matrix_event_room_message_feedback));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_message_feedback_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback = MATRIX_EVENT_ROOM_MESSAGE_FEEDBACK(gobject);
switch (property_id) {
case PROP_FEEDBACK_TYPE:
matrix_event_room_message_feedback_set_feedback_type(matrix_event_room_message_feedback, g_value_get_string(value));
break;
case PROP_TARGET_EVENT_ID:
matrix_event_room_message_feedback_set_target_event_id(matrix_event_room_message_feedback, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_message_feedback_class_init(MatrixEventRoomMessageFeedbackClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_message_feedback_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_message_feedback_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_message_feedback_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_message_feedback_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_message_feedback_finalize;
/**
* MatrixEventRoomMessageFeedback:feedback-type:
*
* The type of the feedback. As the use of this event type is discouraged, this SDK doesnt
* implement this as an actual enum, but the only recognised values are `received` and `read`.
*/
matrix_event_room_message_feedback_properties[PROP_FEEDBACK_TYPE] = g_param_spec_string(
"feedback-type", "feedback-type", "feedback-type",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_FEEDBACK_TYPE, matrix_event_room_message_feedback_properties[PROP_FEEDBACK_TYPE]);
/**
* MatrixEventRoomMessageFeedback:target-event-id:
*
* The event that this feedback is related to.
*/
matrix_event_room_message_feedback_properties[PROP_TARGET_EVENT_ID] = g_param_spec_string(
"target-event-id", "target-event-id", "target-event-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TARGET_EVENT_ID, matrix_event_room_message_feedback_properties[PROP_TARGET_EVENT_ID]);
}
static void
matrix_event_room_message_feedback_init(MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback)
{
MatrixEventRoomMessageFeedbackPrivate *priv = matrix_event_room_message_feedback_get_instance_private(matrix_event_room_message_feedback);
priv->_feedback_type = NULL;
priv->_target_event_id = NULL;
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_MESSAGE_FEEDBACK_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_MESSAGE_FEEDBACK_H__
# include <glib-object.h>
# include "matrix-event-room-base.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_MESSAGE_FEEDBACK (matrix_event_room_message_feedback_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomMessageFeedback, matrix_event_room_message_feedback, MATRIX_EVENT, ROOM_MESSAGE_FEEDBACK, MatrixEventRoom);
struct _MatrixEventRoomMessageFeedbackClass {
MatrixEventRoomClass parent_class;
};
MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback_new(void);
MatrixEventRoomMessageFeedback *matrix_event_room_message_feedback_construct(GType object_type);
const gchar *matrix_event_room_message_feedback_get_feedback_type(MatrixEventRoomMessageFeedback *event);
void matrix_event_room_message_feedback_set_feedback_type(MatrixEventRoomMessageFeedback *event, const gchar *feedback_type);
const gchar *matrix_event_room_message_feedback_get_target_event_id(MatrixEventRoomMessageFeedback *event);
void matrix_event_room_message_feedback_set_target_event_id(MatrixEventRoomMessageFeedback *event, const gchar *target_event_id);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_MESSAGE_FEEDBACK_H__ */

View File

@@ -1,84 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.message.feedback event.
*
* Usage of this event is discouraged in favour of the receipts
* module. Most clients will not recognise this event.
*
* Feedback events are events sent to acknowledge a message in some
* way. There are two supported acknowledgements: `delivered` (sent
* when the event has been received) and `read` (sent when the event
* has been observed by the end-user). The `target_event_id` should
* reference the `m.room.message` event being acknowledged.
*/
public class Matrix.Event.RoomMessageFeedback : Matrix.Event.Room {
/**
* The type of the feedback. As the use of this event type is
* discouraged, Matrix GLib SDK doesnt implement this as an
* actual enum.
*/
public string? feedback_type { get; set; default = null; }
/**
* The event that this feedback is related to.
*/
public string? target_event_id { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("type")) != null) {
_feedback_type = node.get_string();
} else {
warning("content.type is missing from a m.room.message.feedback event");
}
if ((node = content_root.get_member("target_event_id")) != null) {
_target_event_id = node.get_string();
} else {
warning("content.target_event_id is missing from a m.room.message.feedback event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if ((_feedback_type == null) || (_target_event_id == null)) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.message.feedback without all fields set");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
content_root.set_string_member("type", _feedback_type);
content_root.set_string_member("target_event_id", _target_event_id);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,370 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-message.h"
#include "matrix-enumtypes.h"
/**
* SECTION:matrix-event-room-message
* @short_description: event to hold messages in a room
*
* This is the default event handler for `m.room.message` events.
*
* This event is used when sending messages in a room. Messages are not limited to be text.
* The `msgtype` key outlines the type of message, e.g. text, audio, image, video, etc. The
* `body` key is text and MUST be used with every kind of `msgtype` as a fallback mechanism for
* when a client cannot render a message. This allows clients to display *something* even if
* it is just plain text.
*/
enum {
PROP_0,
PROP_BODY,
PROP_MESSAGE,
PROP_FALLBACK_CONTENT,
NUM_PROPERTIES
};
static GParamSpec* matrix_event_room_message_properties[NUM_PROPERTIES];
typedef struct {
MatrixMessageBase* _message;
gchar *body;
JsonNode* _fallback_content;
} MatrixEventRoomMessagePrivate;
/**
* MatrixEventRoomMessage:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomMessage, matrix_event_room_message, MATRIX_EVENT_TYPE_ROOM);
static void
matrix_event_room_message_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomMessagePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
MatrixMessageBase *message;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_message_get_instance_private(MATRIX_EVENT_ROOM_MESSAGE(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
json_node_unref(priv->_fallback_content);
priv->_fallback_content = NULL;
content_root = json_node_get_object(content_node);
node = json_object_get_member(content_root, "body");
g_free(priv->body);
priv->body = g_strdup(json_node_get_string(node));
/*
* We don't want to fail on unknown message types, so let's save the JSON content
* instead. Silent (ie. without exception) null is only returned if there is no handler class
* installed
*/
message = matrix_message_base_new_from_json(content_node, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
priv->_message = message;
if (message == NULL) {
priv->_fallback_content = json_node_ref(content_node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_message_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_message_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomMessagePrivate *priv;
JsonObject *root;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_message_get_instance_private(MATRIX_EVENT_ROOM_MESSAGE(matrix_event_base));
if (priv->_message == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.message event without content");
return;
}
root = json_node_get_object(json_data);
node = matrix_message_base_get_json(priv->_message, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
return;
}
json_object_set_member(root, "content", node);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_message_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomMessage *
matrix_event_room_message_construct(GType object_type)
{
return (MatrixEventRoomMessage *)matrix_event_room_construct(object_type);
}
/**
* matrix_event_room_message_new:
*
* Create a new #MatrixEventRoomMessage object.
*
* Returns: (transfer full): a new #MatrixEventRoomMessage object
*/
MatrixEventRoomMessage *
matrix_event_room_message_new(void) {
return matrix_event_room_message_construct(MATRIX_EVENT_TYPE_ROOM_MESSAGE);
}
/**
* matrix_event_room_message_get_message:
* @event: a #MatrixEventRoomMessage
*
* Get the message object from @event, if it could be resoled to a known message type.
* Resolution is done by matrix_message_get_handler().
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a #MatrixMessageBase derived object
*/
MatrixMessageBase *
matrix_event_room_message_get_message(MatrixEventRoomMessage *matrix_event_room_message)
{
MatrixEventRoomMessagePrivate *priv;
g_return_val_if_fail(matrix_event_room_message != NULL, NULL);
priv = matrix_event_room_message_get_instance_private(matrix_event_room_message);
return priv->_message;
}
/**
* matrix_event_room_message_set_message:
* @event: a #MatrixEventRoomMessage
* @message: (transfer none): a #MatrixMessageBase derived object
*
* Set the message of @event.
*
* @event gets a reference on @message, so it is safe to unref it after calling this function.
*/
void
matrix_event_room_message_set_message(MatrixEventRoomMessage *matrix_event_room_message, MatrixMessageBase *message)
{
MatrixEventRoomMessagePrivate *priv;
g_return_if_fail(matrix_event_room_message != NULL);
priv = matrix_event_room_message_get_instance_private(matrix_event_room_message);
if (message != priv->_message) {
g_object_unref(priv->_message);
priv->_message = g_object_ref(message);
g_object_notify_by_pspec((GObject *)matrix_event_room_message, matrix_event_room_message_properties[PROP_MESSAGE]);
}
}
/**
* matrix_event_room_message_get_fallback_content:
* @event: a #MatrixEventRoomMessage
*
* Get the fallback content from @event.
*/
JsonNode *
matrix_event_room_message_get_fallback_content(MatrixEventRoomMessage *matrix_event_room_message)
{
MatrixEventRoomMessagePrivate *priv;
g_return_val_if_fail(matrix_event_room_message != NULL, NULL);
priv = matrix_event_room_message_get_instance_private(matrix_event_room_message);
return priv->_fallback_content;
}
/**
* matrix_event_room_message_get_body:
* @event: a #MatrixEventRoomMessage
*
* Get the body (ie. fallback textual content) of @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the message body
*/
const gchar *
matrix_event_room_message_get_body(MatrixEventRoomMessage *event)
{
MatrixEventRoomMessagePrivate *priv = matrix_event_room_message_get_instance_private(event);
g_return_val_if_fail(event != NULL, NULL);
return priv->body;
}
/**
* matrix_event_room_message_set_body:
* @event: a #MatrixEventRoomMessage
* @body: (transfer none) (nullable): the textual body of the message
*
* Set the textual content of @event.
*/
void
matrix_event_room_message_set_body(MatrixEventRoomMessage *event, const gchar *body)
{
MatrixEventRoomMessagePrivate *priv = matrix_event_room_message_get_instance_private(event);
g_return_if_fail(event != NULL);
if (g_strcmp0(body, priv->body) != 0) {
g_free(priv->body);
priv->body = g_strdup(body);
g_object_notify_by_pspec(G_OBJECT(event), matrix_event_room_message_properties[PROP_BODY]);
}
}
static void
matrix_event_room_message_finalize(GObject *gobject)
{
MatrixEventRoomMessagePrivate *priv = matrix_event_room_message_get_instance_private(MATRIX_EVENT_ROOM_MESSAGE(gobject));
g_object_unref(priv->_message);
json_node_unref(priv->_fallback_content);
G_OBJECT_CLASS(matrix_event_room_message_parent_class)->finalize(gobject);
}
static void
matrix_event_room_message_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomMessage *matrix_event_room_message = MATRIX_EVENT_ROOM_MESSAGE(gobject);
switch (property_id) {
case PROP_MESSAGE:
g_value_set_object(value, matrix_event_room_message_get_message(matrix_event_room_message));
break;
case PROP_FALLBACK_CONTENT:
g_value_set_boxed(value, matrix_event_room_message_get_fallback_content(matrix_event_room_message));
break;
case PROP_BODY:
g_value_set_string(value, matrix_event_room_message_get_body(matrix_event_room_message));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_message_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomMessage *matrix_event_room_message = MATRIX_EVENT_ROOM_MESSAGE(gobject);
switch (property_id) {
case PROP_MESSAGE:
matrix_event_room_message_set_message(matrix_event_room_message, g_value_get_object (value));
break;
case PROP_BODY:
matrix_event_room_message_set_body(matrix_event_room_message, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_message_class_init(MatrixEventRoomMessageClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_message_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_message_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_message_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_message_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_message_finalize;
/**
* MatrixEventRoomMessage:message:
*
* The message as a #MatrixMessageBase derived object.
*/
matrix_event_room_message_properties[PROP_MESSAGE] = g_param_spec_object(
"message", "message", "message",
MATRIX_MESSAGE_TYPE_BASE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_MESSAGE, matrix_event_room_message_properties[PROP_MESSAGE]);
/**
* MatrixEventRoomMessage:fallback-content:
*
* The message as a JSON object. This gets set by matrix_message_base_new_from_json() if
* no handler is installed for the given message type.
*/
matrix_event_room_message_properties[PROP_FALLBACK_CONTENT] = g_param_spec_boxed(
"fallback-content", "fallback-content", "fallback-content",
JSON_TYPE_NODE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_FALLBACK_CONTENT, matrix_event_room_message_properties[PROP_FALLBACK_CONTENT]);
/**
* MatrixEventRoomMessage:body:
*
* The fallback textual body of the message.
*/
matrix_event_room_message_properties[PROP_BODY] = g_param_spec_string(
"body", "body", "body",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_BODY, matrix_event_room_message_properties[PROP_BODY]);
}
static void
matrix_event_room_message_init(MatrixEventRoomMessage *matrix_event_room_message)
{
MatrixEventRoomMessagePrivate *priv = matrix_event_room_message_get_instance_private(matrix_event_room_message);
priv->_message = NULL;
priv->_fallback_content = NULL;
}

View File

@@ -0,0 +1,46 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_MESSAGE_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_MESSAGE_H__
# include <glib-object.h>
# include "matrix-event-room-base.h"
# include "matrix-message-base.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_MESSAGE matrix_event_room_message_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomMessage, matrix_event_room_message, MATRIX_EVENT, ROOM_MESSAGE, MatrixEventRoom);
struct _MatrixEventRoomMessageClass {
MatrixEventRoomClass parent_class;
};
MatrixEventRoomMessage *matrix_event_room_message_new(void);
MatrixEventRoomMessage *matrix_event_room_message_construct(GType object_type);
GType matrix_message_base_get_type(void) G_GNUC_CONST;
MatrixMessageBase *matrix_event_room_message_get_message(MatrixEventRoomMessage *event);
void matrix_event_room_message_set_message(MatrixEventRoomMessage *event, MatrixMessageBase *message);
JsonNode *matrix_event_room_message_get_fallback_content(MatrixEventRoomMessage *event);
const gchar *matrix_event_room_message_get_body(MatrixEventRoomMessage *event);
void matrix_event_room_message_set_body(MatrixEventRoomMessage *event, const gchar *body);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_MESSAGE_H__ */

View File

@@ -1,90 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold an m.room.message event
*
* This event is used when sending messages in a room. Messages are
* not limited to be text. The `msgtype` key outlines the type of
* message, e.g. text, audio, image, video, etc. The `body` key is
* text and MUST be used with every kind of `msgtype` as a fallback
* mechanism for when a client cannot render a message. This allows
* clients to display *something* even if it is just plain text.
*/
public class Matrix.Event.RoomMessage : Matrix.Event.Room {
/**
* The message as a Matrix.Message object.
*/
public Matrix.Message.Base? message { get; set; default = null; }
/**
* The message as a JSON object. This gets set by
* Matrix.Message.Base.new_from_json if no handler is installed
* for the given message type.
*/
public Json.Node? fallback_content {
get {
return _fallback_content;
}
}
private Json.Node? _fallback_content;
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_node = json_data.get_object().get_member("content");
try {
_message = Matrix.Message.Base.new_from_json(content_node);
// We don't want to fail on unknown message types, so
// let's save the JSON content instead. Silent
// (ie. without exception) null is only returned if there
// is no handler class installed
if (_message == null) {
_fallback_content = content_node;
} else {
_fallback_content = null;
}
} catch (GLib.Error e) {
throw new Matrix.Error.INVALID_TYPE(
"Error during message initialization:%s",
e.message);
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_message == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.message event without content");
}
var root = json_data.get_object();
root.set_member("content", _message.json);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,258 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-name.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-name
* @short_description: event to handle room name changes
*
* This is the default event handler for `m.room.name` events.
*
* A room has an opaque room ID which is not human-friendly to read. A room alias is
* human-friendly, but not all rooms have room aliases. The room name is a human-friendly
* string designed to be displayed to the end-user. The room name is not unique, as multiple
* rooms can have the same room name set. The room name can also be set when creating a room
* using matrix_api_create_room() with name set.
*/
enum {
PROP_0,
PROP_NAME,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_name_properties[NUM_PROPERTIES];
typedef struct {
gchar* _name;
} MatrixEventRoomNamePrivate;
/**
* MatrixEventRoomName:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomName, matrix_event_room_name, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_name_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomNamePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_name_get_instance_private(MATRIX_EVENT_ROOM_NAME(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if (DEBUG && ((node = json_object_get_member(root, "state_key")) != NULL)) {
gchar *state_key = (gchar *)json_node_get_string(node);
if ((state_key != NULL) && (*state_key == 0)) {
g_warning("state_key of a m.room.name event is non-empty");
}
}
if ((node = json_object_get_member(content_root, "name")) != NULL) {
g_free(priv->_name);
priv->_name = g_strdup(json_node_get_string(node));
} else {
g_warning("content.name is missing from a m.room.name event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_name_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_name_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomNamePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
const gchar *state_key;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_name_get_instance_private(MATRIX_EVENT_ROOM_NAME(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't send a m.room.name with a non-empty state key");
return;
}
if ((priv->_name == NULL) || (*(priv->_name) == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't send a m.room.name event without a name");
return;
}
json_object_set_string_member(content_root, "name", priv->_name);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_name_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomName *
matrix_event_room_name_construct(GType object_type)
{
return (MatrixEventRoomName *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_name_new:
*
* Create a new #MatrixEventRoomName object.
*
* Returns: (transfer full): a new #MatrixEventRoomName object
*/
MatrixEventRoomName *
matrix_event_room_name_new(void)
{
return matrix_event_room_name_construct(MATRIX_EVENT_TYPE_ROOM_NAME);
}
/**
* matrix_event_room_name_get_name:
* @event: a #MatrixEventRoomName
*
* Get the name from @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the room name
*/
const gchar *
matrix_event_room_name_get_name(MatrixEventRoomName *matrix_event_room_name)
{
MatrixEventRoomNamePrivate *priv;
g_return_val_if_fail(matrix_event_room_name != NULL, NULL);
priv = matrix_event_room_name_get_instance_private(matrix_event_room_name);
return priv->_name;
}
/**
* matrix_event_room_name_set_name:
* @event: a #MatrixEventRoomName
* @name: a room name
*
* Set the name in @event.
*/
void
matrix_event_room_name_set_name(MatrixEventRoomName *matrix_event_room_name, const gchar *name)
{
MatrixEventRoomNamePrivate *priv;
g_return_if_fail(matrix_event_room_name != NULL);
priv = matrix_event_room_name_get_instance_private(matrix_event_room_name);
if (g_strcmp0(name, priv->_name) != 0) {
g_free(priv->_name);
priv->_name = g_strdup(name);
g_object_notify_by_pspec((GObject *)matrix_event_room_name, matrix_event_room_name_properties[PROP_NAME]);
}
}
static void
matrix_event_room_name_finalize(GObject *gobject)
{
MatrixEventRoomNamePrivate *priv = matrix_event_room_name_get_instance_private(MATRIX_EVENT_ROOM_NAME(gobject));
g_free(priv->_name);
G_OBJECT_CLASS(matrix_event_room_name_parent_class)->finalize(gobject);
}
static void
matrix_event_room_name_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomName *matrix_event_room_name = MATRIX_EVENT_ROOM_NAME(gobject);
switch (property_id) {
case PROP_NAME:
g_value_set_string(value, matrix_event_room_name_get_name(matrix_event_room_name));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_name_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomName *matrix_event_room_name = MATRIX_EVENT_ROOM_NAME(gobject);
switch (property_id) {
case PROP_NAME:
matrix_event_room_name_set_name(matrix_event_room_name, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_name_class_init(MatrixEventRoomNameClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_name_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_name_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_name_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_name_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_name_finalize;
/**
* MatrixEventRoomName:name:
*
* The room name.
*/
matrix_event_room_name_properties[PROP_NAME] = g_param_spec_string(
"name", "name", "name",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_NAME, matrix_event_room_name_properties[PROP_NAME]);
}
static void
matrix_event_room_name_init(MatrixEventRoomName *matrix_event_room_name)
{
MatrixEventRoomNamePrivate *priv = matrix_event_room_name_get_instance_private(matrix_event_room_name);
priv->_name = NULL;
}

View File

@@ -0,0 +1,41 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_NAME_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_NAME_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_ROOM_NAME matrix_event_room_name_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomName, matrix_event_room_name, MATRIX_EVENT, ROOM_NAME, MatrixEventState);
struct _MatrixEventRoomNameClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomName *matrix_event_room_name_new(void);
MatrixEventRoomName *matrix_event_room_name_construct(GType object_type);
const gchar *matrix_event_room_name_get_name(MatrixEventRoomName *event);
void matrix_event_room_name_set_name(MatrixEventRoomName *event, const gchar *name);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_NAME_H__ */

View File

@@ -1,76 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.name event.
*
* A room has an opaque room ID which is not human-friendly to read. A
* room alias is human-friendly, but not all rooms have room
* aliases. The room name is a human-friendly string designed to be
* displayed to the end-user. The room name is not unique, as multiple
* rooms can have the same room name set. The room name can also be
* set when creating a room using createRoom with the name key.
*/
public class Matrix.Event.RoomName : Matrix.Event.State {
public string? name { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.name event is non-empty");
}
}
if ((node = content_root.get_member("name")) != null) {
_name = node.get_string();
} else {
warning("content.name is missing from a m.room.name event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't send a m.room.name with a non-empty state key");
}
if (_name == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't send a m.room.name event without a name");
}
content_root.set_string_member("name", _name);
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,799 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-power-levels.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-power-levels
* @short_description: event to control power level assignments
*
* This is the default event handler for `m.room.power_levels` events.
*
* This event specifies the minimum level a user must have in order to perform a certain
* action. It also specifies the levels of each user in the room. If a `user_id` is in the
* users list, then that `user_id` has the associated power level. Otherwise they have the
* default level set in `users_default`. If `users_default` is not supplied, it is assumed to
* be 0. The level required to send a certain event is governed by the keys `events`,
* `state_default` and `events_default`. If an event type is specified in events, then the
* user must have at least the level specified in order to send that event. If the event type
* is not supplied, it defaults to `events_default` for message events and `state_default` for
* state events.
*/
enum {
PROP_0,
PROP_USERS_DEFAULT,
PROP_EVENTS_DEFAULT,
PROP_STATE_DEFAULT,
PROP_BAN,
PROP_KICK,
PROP_REDACT,
PROP_INVITE,
PROP_EVENT_LEVELS,
PROP_USER_LEVELS,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_power_levels_properties[NUM_PROPERTIES];
typedef struct {
gint _users_default;
gint _events_default;
gint _state_default;
gint _ban;
gint _kick;
gint _redact;
gint _invite;
GHashTable* _event_levels;
GHashTable* _user_levels;
} MatrixEventRoomPowerLevelsPrivate;
/**
* MatrixEventRoomPowerLevels:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomPowerLevels, matrix_event_room_power_levels, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_power_levels_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomPowerLevelsPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_power_levels_get_instance_private(MATRIX_EVENT_ROOM_POWER_LEVELS(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
#if DEBUG
if ((node = json_object_get_member(root, "state_key")) != NULL) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key == 0)) {
g_warning("state_key of a m.room.power_levels event is non-empty");
}
}
#endif
if ((node = json_object_get_member(content_root, "ban")) != NULL) {
priv->_ban = json_node_get_int(node);
} else {
g_warning("content.ban is missing from a m.room.power_levels event");
}
if ((node = json_object_get_member(content_root, "kick")) != NULL) {
priv->_kick = json_node_get_int(node);
} else {
g_warning("content.kick is missing from a m.room.power_levels event");
}
if ((node = json_object_get_member(content_root, "redact")) != NULL) {
priv->_redact = json_node_get_int(node);
} else {
g_warning("content.redact is missing from a m.room.power_levels event");
}
if ((node = json_object_get_member(content_root, "events_default")) != NULL) {
priv->_events_default = json_node_get_int(node);
} else {
g_warning("content.events_default is missing from a m.room.power_levels event");
}
if ((node = json_object_get_member(content_root, "state_default")) != NULL) {
priv->_state_default = json_node_get_int(node);
} else {
g_warning("content.state_default is missing from a m.room.power_levels event");
}
if ((node = json_object_get_member(content_root, "users_default")) != NULL) {
priv->_users_default = json_node_get_int(node);
}
if ((node = json_object_get_member(content_root, "invite")) != NULL) {
priv->_invite = json_node_get_int(node);
}
if ((node = json_object_get_member(content_root, "events")) != NULL) {
JsonObject *events_root;
JsonObjectIter iter;
const gchar *event_name;
JsonNode *event_node;
g_hash_table_remove_all(priv->_event_levels);
events_root = json_node_get_object(node);
json_object_iter_init(&iter, events_root);
while (json_object_iter_next(&iter, &event_name, &event_node)) {
g_hash_table_insert(priv->_event_levels, g_strdup(event_name), GINT_TO_POINTER(json_node_get_int(event_node)));
}
}
if ((node = json_object_get_member(content_root, "users")) != NULL) {
JsonObject *users_root;
JsonObjectIter iter;
const gchar *user_id;
JsonNode *user_node;
g_hash_table_remove_all(priv->_user_levels);
users_root = json_node_get_object(node);
json_object_iter_init(&iter, users_root);
while (json_object_iter_next(&iter, &user_id, &user_node)) {
g_hash_table_insert(priv->_user_levels, g_strdup(user_id), GINT_TO_POINTER(json_node_get_int(user_node)));
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_power_levels_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_power_levels_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomPowerLevelsPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonObject *users_root;
JsonObject *events_root;
JsonNode *content_node;
JsonNode *users_node;
JsonNode *events_node;
GHashTableIter iter;
const gchar *state_key;
gpointer key;
gpointer value;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_power_levels_get_instance_private(MATRIX_EVENT_ROOM_POWER_LEVELS(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.power_levels event with a non-empty state_key");
return;
}
if (priv->_user_levels == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't create an m.room.power_levels event without a content.users key");
return;
}
if (priv->_event_levels == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't create an m.room.power_levels event without a content.events key");
return;
}
json_object_set_int_member(content_root, "ban", priv->_ban);
json_object_set_int_member(content_root, "kick", priv->_kick);
json_object_set_int_member(content_root, "redact", priv->_redact);
json_object_set_int_member(content_root, "state_default", priv->_state_default);
json_object_set_int_member(content_root, "events_default", priv->_events_default);
users_root = json_object_new();
users_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(users_node, users_root);
g_hash_table_iter_init(&iter, priv->_user_levels);
while (g_hash_table_iter_next(&iter, &key, &value)) {
json_object_set_int_member(users_root, g_strdup(key), GPOINTER_TO_INT(value));
}
json_object_set_member(content_root, "users", users_node);
events_root = json_object_new();
events_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(events_node, events_root);
g_hash_table_iter_init(&iter, priv->_event_levels);
while (g_hash_table_iter_next(&iter, &key, &value)) {
json_object_set_int_member(events_root, g_strdup(key), GPOINTER_TO_INT(value));
}
json_object_set_member(content_root, "events", events_node);
MATRIX_EVENT_BASE_CLASS(matrix_event_room_power_levels_parent_class)->to_json(matrix_event_base, json_data, error);
}
/**
* matrix_event_room_power_levels_set_user_level:
* @event: a #MatrixEventRoomPowerLevels
* @user_id: (transfer none) (not nullable): a Matrix ID
* @level: the level to set for @user_id
*
* Set the level of @user_id to @level in @event.
*/
void
matrix_event_room_power_levels_set_user_level(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, const gchar *user_id, gint level)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
g_return_if_fail(user_id != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
g_hash_table_insert(priv->_user_levels, g_strdup(user_id), GINT_TO_POINTER(level));
}
/**
* matrix_event_room_power_levels_set_event_level:
* @event: a #MatrixEventRoomPowerLevels
* @event_type: an event type name
* @level: the required level for sending @event_type messages
*
* Set the level required to send messages with type @event_type to @level.
*/
void
matrix_event_room_power_levels_set_event_level(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, const gchar *event_type, gint level)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
g_return_if_fail(event_type != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
g_hash_table_insert(priv->_event_levels, g_strdup(event_type), GINT_TO_POINTER(level));
}
MatrixEventRoomPowerLevels *
matrix_event_room_power_levels_construct(GType object_type)
{
return (MatrixEventRoomPowerLevels *)matrix_event_state_construct(object_type);
}
/**
* matrix_event_room_power_levels_new:
*
* Create a new #MatrixEventRoomPowerLevels object
*
* Returns: (transfer full): a new #MatrixEventRoomPowerLevels object
*/
MatrixEventRoomPowerLevels *
matrix_event_room_power_levels_new(void)
{
return matrix_event_room_power_levels_construct(MATRIX_EVENT_TYPE_ROOM_POWER_LEVELS);
}
/**
* matrix_event_room_power_levels_get_users_default:
* @event: a #MatrixEventRoomPowerLevels
*
* Get the default user level from @event.
*
* Returns: a power level
*/
gint
matrix_event_room_power_levels_get_users_default(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_users_default;
}
/**
* matrix_event_room_power_levels_set_users_default:
* @event: a #MatrixEventRoomPowerLevels
* @users_default: a power level
*
* Set the default user level in @event.
*/
void
matrix_event_room_power_levels_set_users_default(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint users_default)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_users_default != users_default) {
priv->_users_default = users_default;
g_object_notify_by_pspec((GObject *)matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_USERS_DEFAULT]);
}
}
/**
* matrix_event_room_power_levels_get_events_default:
* @event: a #MatrixEventRoomPowerLevels
*
* Get the level required to send messages in @event, if not otherwise set with
* matrix_event_room_power_levels_set_event_level()
*/
gint
matrix_event_room_power_levels_get_events_default(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_events_default;
}
/**
* matrix_event_room_power_levels_set_events_default:
* @event: a #MatrixEventRoomPowerLevels
* @events_default: a power level
*
* Set the event level required for sending message events. This is the default value to be
* used for events that are not set with matrix_event_room_power_levels_set_event_level().
*/
void
matrix_event_room_power_levels_set_events_default(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint events_default)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_events_default != events_default) {
priv->_events_default = events_default;
g_object_notify_by_pspec((GObject *)matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_EVENTS_DEFAULT]);
}
}
gint
matrix_event_room_power_levels_get_state_default(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_state_default;
}
void
matrix_event_room_power_levels_set_state_default(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint state_default)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_state_default != state_default) {
priv->_state_default = state_default;
g_object_notify_by_pspec((GObject *)matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_STATE_DEFAULT]);
}
}
gint
matrix_event_room_power_levels_get_ban(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_ban;
}
void
matrix_event_room_power_levels_set_ban(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint ban)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_ban != ban) {
priv->_ban = ban;
g_object_notify_by_pspec((GObject *) matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_BAN]);
}
}
gint
matrix_event_room_power_levels_get_kick(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_kick;
}
void
matrix_event_room_power_levels_set_kick(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint kick)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_kick != kick) {
priv->_kick = kick;
g_object_notify_by_pspec((GObject *)matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_KICK]);
}
}
gint
matrix_event_room_power_levels_get_redact(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_redact;
}
void
matrix_event_room_power_levels_set_redact(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint redact)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_redact != redact) {
priv->_redact = redact;
g_object_notify_by_pspec((GObject *)matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_REDACT]);
}
}
gint
matrix_event_room_power_levels_get_invite(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, 0);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_invite;
}
void
matrix_event_room_power_levels_set_invite(MatrixEventRoomPowerLevels *matrix_event_room_power_levels, gint invite)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_if_fail(matrix_event_room_power_levels != NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
if (priv->_invite != invite) {
priv->_invite = invite;
g_object_notify_by_pspec((GObject *)matrix_event_room_power_levels, matrix_event_room_power_levels_properties[PROP_INVITE]);
}
}
GHashTable *
matrix_event_room_power_levels_get_event_levels(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_event_levels;
}
/**
* matrix_event_room_power_levels_get_user_levels:
* @event: a #MatrixEventRoomPowerLevels
*
* Get the table of individual user levels from @event.
*
* The returned value is owned by @event and should not be freed.
*
* The returned #GHashTable has user IDs as keys. The value are integer power levels
* converted to pointers; use GPOINTER_TO_INT() to convert them to actual power levels.
*
* Returns: (transfer none) (nullable): a table of user levels
*/
GHashTable *
matrix_event_room_power_levels_get_user_levels(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv;
g_return_val_if_fail(matrix_event_room_power_levels != NULL, NULL);
priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
return priv->_user_levels;
}
static void
matrix_event_room_power_levels_finalize(GObject *gobject)
{
MatrixEventRoomPowerLevelsPrivate *priv = matrix_event_room_power_levels_get_instance_private(MATRIX_EVENT_ROOM_POWER_LEVELS(gobject));
g_hash_table_unref(priv->_event_levels);
g_hash_table_unref(priv->_user_levels);
G_OBJECT_CLASS(matrix_event_room_power_levels_parent_class)->finalize(gobject);
}
static void
matrix_event_room_power_levels_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomPowerLevels *matrix_event_room_power_levels = MATRIX_EVENT_ROOM_POWER_LEVELS(gobject);
switch (property_id) {
case PROP_USERS_DEFAULT:
g_value_set_int(value, matrix_event_room_power_levels_get_users_default(matrix_event_room_power_levels));
break;
case PROP_EVENTS_DEFAULT:
g_value_set_int(value, matrix_event_room_power_levels_get_events_default(matrix_event_room_power_levels));
break;
case PROP_STATE_DEFAULT:
g_value_set_int(value, matrix_event_room_power_levels_get_state_default(matrix_event_room_power_levels));
break;
case PROP_BAN:
g_value_set_int(value, matrix_event_room_power_levels_get_ban(matrix_event_room_power_levels));
break;
case PROP_KICK:
g_value_set_int(value, matrix_event_room_power_levels_get_kick(matrix_event_room_power_levels));
break;
case PROP_REDACT:
g_value_set_int(value, matrix_event_room_power_levels_get_redact(matrix_event_room_power_levels));
break;
case PROP_INVITE:
g_value_set_int(value, matrix_event_room_power_levels_get_invite(matrix_event_room_power_levels));
break;
case PROP_EVENT_LEVELS:
g_value_set_boxed(value, matrix_event_room_power_levels_get_event_levels(matrix_event_room_power_levels));
break;
case PROP_USER_LEVELS:
g_value_set_boxed(value, matrix_event_room_power_levels_get_user_levels(matrix_event_room_power_levels));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_power_levels_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomPowerLevels *matrix_event_room_power_levels = MATRIX_EVENT_ROOM_POWER_LEVELS(gobject);
switch (property_id) {
case PROP_USERS_DEFAULT:
matrix_event_room_power_levels_set_users_default(matrix_event_room_power_levels, g_value_get_int(value));
break;
case PROP_EVENTS_DEFAULT:
matrix_event_room_power_levels_set_events_default(matrix_event_room_power_levels, g_value_get_int(value));
break;
case PROP_STATE_DEFAULT:
matrix_event_room_power_levels_set_state_default(matrix_event_room_power_levels, g_value_get_int(value));
break;
case PROP_BAN:
matrix_event_room_power_levels_set_ban(matrix_event_room_power_levels, g_value_get_int(value));
break;
case PROP_KICK:
matrix_event_room_power_levels_set_kick(matrix_event_room_power_levels, g_value_get_int(value));
break;
case PROP_REDACT:
matrix_event_room_power_levels_set_redact(matrix_event_room_power_levels, g_value_get_int(value));
break;
case PROP_INVITE:
matrix_event_room_power_levels_set_invite(matrix_event_room_power_levels, g_value_get_int(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_power_levels_class_init(MatrixEventRoomPowerLevelsClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_power_levels_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_power_levels_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_power_levels_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_power_levels_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_power_levels_finalize;
/**
* MatrixEventRoomPowerLevels:users-default:
*
* The default power level for every user in the room, unless their user ID is mentioned
* in the #MatrixEventRoomPowerLevels:users property.
*/
matrix_event_room_power_levels_properties[PROP_USERS_DEFAULT] = g_param_spec_int(
"users-default", "users-default", "users-default",
G_MININT, G_MAXINT, 0,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_USERS_DEFAULT, matrix_event_room_power_levels_properties[PROP_USERS_DEFAULT]);
/**
* MatrixEventRoomPowerLevels:events-default:
*
* The default level required to send message events. Can be overridden with values in
* the #MatrixEventRoomPowerLevels:events property.
*/
matrix_event_room_power_levels_properties[PROP_EVENTS_DEFAULT] = g_param_spec_int(
"events-default", "events-default", "events-default",
G_MININT, G_MAXINT, 0,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_EVENTS_DEFAULT, matrix_event_room_power_levels_properties[PROP_EVENTS_DEFAULT]);
/**
* MatrixEventRoomPowerLevels:state-default:
*
* The default level required to send state events. Can be overridden with values in the
* #MatrixEventRoomPowerLevels:events property.
*/
matrix_event_room_power_levels_properties[PROP_STATE_DEFAULT] = g_param_spec_int(
"state-default", "state-default", "state-default",
G_MININT, G_MAXINT, 10,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_STATE_DEFAULT, matrix_event_room_power_levels_properties[PROP_STATE_DEFAULT]);
/**
* MatrixEventRoomPowerLevels:ban:
*
* The level required to ban a user.
*/
matrix_event_room_power_levels_properties[PROP_BAN] = g_param_spec_int(
"ban", "ban", "ban",
G_MININT, G_MAXINT, 5,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_BAN, matrix_event_room_power_levels_properties[PROP_BAN]);
/**
* MatrixEventRoomPowerLevels:kick:
*
* The level required to kick a user.
*/
matrix_event_room_power_levels_properties[PROP_KICK] = g_param_spec_int(
"kick", "kick", "kick",
G_MININT, G_MAXINT, 5,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KICK, matrix_event_room_power_levels_properties[PROP_KICK]);
/**
* MatrixEventRoomPowerLevels:redact:
*
* The level required to redact an event.
*/
matrix_event_room_power_levels_properties[PROP_REDACT] = g_param_spec_int(
"redact", "redact", "redact",
G_MININT, G_MAXINT, 20,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_REDACT, matrix_event_room_power_levels_properties[PROP_REDACT]);
/**
* MatrixEventRoomPowerLevels:invite:
*
* The level required to invite someone.
*/
matrix_event_room_power_levels_properties[PROP_INVITE] = g_param_spec_int(
"invite", "invite", "invite",
G_MININT, G_MAXINT, 0,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_INVITE, matrix_event_room_power_levels_properties[PROP_INVITE]);
/**
* MatrixEventRoomPowerLevels:event-levels:
*
* A hash map to store the required level to send specific events.
*/
matrix_event_room_power_levels_properties[PROP_EVENT_LEVELS] = g_param_spec_boxed(
"event-levels", "event-levels", "event-levels",
G_TYPE_HASH_TABLE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_EVENT_LEVELS, matrix_event_room_power_levels_properties[PROP_EVENT_LEVELS]);
/**
* MatrixEventRoomPowerLevels:user-levels:
*
* A hash map to store current level for individual users.
*/
matrix_event_room_power_levels_properties[PROP_USER_LEVELS] = g_param_spec_boxed(
"user-levels", "user-levels", "user-levels",
G_TYPE_HASH_TABLE,
G_PARAM_STATIC_STRINGS | G_PARAM_READABLE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_USER_LEVELS, matrix_event_room_power_levels_properties[PROP_USER_LEVELS]);
}
static void
matrix_event_room_power_levels_init(MatrixEventRoomPowerLevels *matrix_event_room_power_levels)
{
MatrixEventRoomPowerLevelsPrivate *priv = matrix_event_room_power_levels_get_instance_private(matrix_event_room_power_levels);
priv->_users_default = 0;
priv->_events_default = 0;
priv->_state_default = 10;
priv->_ban = 5;
priv->_kick = 5;
priv->_redact = 20;
priv->_invite = 0;
priv->_event_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
priv->_user_levels = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
}

View File

@@ -0,0 +1,57 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_POWER_LEVELS_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_POWER_LEVELS_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_POWER_LEVELS (matrix_event_room_power_levels_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomPowerLevels, matrix_event_room_power_levels, MATRIX_EVENT, ROOM_POWER_LEVELS, MatrixEventState);
struct _MatrixEventRoomPowerLevelsClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomPowerLevels *matrix_event_room_power_levels_new(void);
MatrixEventRoomPowerLevels *matrix_event_room_power_levels_construct(GType object_type);
void matrix_event_room_power_levels_set_user_level(MatrixEventRoomPowerLevels *event, const gchar *user_id, gint level);
void matrix_event_room_power_levels_set_event_level(MatrixEventRoomPowerLevels *event, const gchar *event_type, gint level);
gint matrix_event_room_power_levels_get_users_default(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_users_default(MatrixEventRoomPowerLevels *event, gint users_default);
gint matrix_event_room_power_levels_get_events_default(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_events_default(MatrixEventRoomPowerLevels *event, gint events_default);
gint matrix_event_room_power_levels_get_state_default(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_state_default(MatrixEventRoomPowerLevels *event, gint state_default);
gint matrix_event_room_power_levels_get_ban(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_ban(MatrixEventRoomPowerLevels *event, gint ban);
gint matrix_event_room_power_levels_get_kick(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_kick(MatrixEventRoomPowerLevels *event, gint kick);
gint matrix_event_room_power_levels_get_redact(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_redact(MatrixEventRoomPowerLevels *event, gint redact);
gint matrix_event_room_power_levels_get_invite(MatrixEventRoomPowerLevels *event);
void matrix_event_room_power_levels_set_invite(MatrixEventRoomPowerLevels *event, gint invite);
GHashTable *matrix_event_room_power_levels_get_event_levels(MatrixEventRoomPowerLevels *event);
GHashTable *matrix_event_room_power_levels_get_user_levels(MatrixEventRoomPowerLevels *event);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_POWER_LEVELS_H__ */

View File

@@ -1,232 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to handle m.room.power_levels event
*
* This event specifies the minimum level a user must have in order to
* perform a certain action. It also specifies the levels of each user
* in the room. If a user_id is in the users list, then that user_id
* has the associated power level. Otherwise they have the default
* level users_default. If users_default is not supplied, it is
* assumed to be 0. The level required to send a certain event is
* governed by events, state_default and events_default. If an event
* type is specified in events, then the user must have at least the
* level specified in order to send that event. If the event type is
* not supplied, it defaults to events_default for Message Events and
* state_default for State Events.
*/
public class Matrix.Event.RoomPowerLevels : Matrix.Event.State {
/**
* The default power level for every user in the room, unless
* their user_id is mentioned in the users key.
*/
public int users_default { get; set; default = 0; }
/**
* The default level required to send message events. Can be
* overridden by the events key.
*/
public int events_default { get; set; default = 0; }
/**
* The default level required to send state events. Can be
* overridden by the events key.
*/
public int state_default { get; set; default = 10; }
/**
* The level required to ban a user.
*/
public int ban { get; set; default = 5; }
/**
* The level required to kick a user.
*/
public int kick { get; set; default = 5; }
/**
* The level required to redact an event.
*/
public int redact { get; set; default = 20; }
/**
* The level required to invite someone.
*/
public int invite { get; set; default = 0; }
/**
* A hash map to store the required level to send specific events.
*/
public HashTable<string, int?> event_levels {
get {
return _event_levels;
}
}
/**
* A hash map to store current level for individual users.
*/
public HashTable<string, int?> user_levels {
get {
return _user_levels;
}
}
private HashTable<string, int?> _event_levels =
new HashTable<string, int?>(str_hash, str_equal);
private HashTable<string, int?> _user_levels =
new HashTable<string, int?>(str_hash, str_equal);
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("content")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.power_levels event is non-empty");
}
}
if ((node = content_root.get_member("ban")) != null) {
_ban = (int)node.get_int();
} else {
warning("content.ban is missing from a m.room.power_levels event");
}
if ((node = content_root.get_member("kick")) != null) {
_kick = (int)node.get_int();
} else {
warning("content.kick is missing from a m.room.power_levels event");
}
if ((node = content_root.get_member("redact")) != null) {
_redact = (int)node.get_int();
} else {
warning("content.redact is missing from a m.room.power_levels event");
}
if ((node = content_root.get_member("events_default")) != null) {
_events_default = (int)node.get_int();
} else {
warning("content.events_default is missing from a m.room.power_levels event");
}
if ((node = content_root.get_member("state_default")) != null) {
_state_default = (int)node.get_int();
} else {
warning("content.state_default is missing from a m.room.power_levels event");
}
if ((node = content_root.get_member("users_default")) != null) {
_users_default = (int)node.get_int();
}
if ((node = content_root.get_member("invite")) != null) {
_invite = (int)node.get_int();
}
if ((node = content_root.get_member("events")) != null) {
_event_levels.remove_all();
node.get_object().foreach_member((obj, event_name, event_node) => {
_event_levels[event_name] = (int)event_node.get_int();
});
}
if ((node = content_root.get_member("users")) != null) {
_user_levels.remove_all();
node.get_object().foreach_member((obj, user_id, user_node) => {
_user_levels[user_id] = (int)user_node.get_int();
});
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.power_levels event with a non-empty state_key");
}
if (_user_levels == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't create an m.room.power_levels event without a content.users key");
}
if (_event_levels == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't create an m.room.power_levels event without a content.events key");
}
content_root.set_int_member("ban", _ban);
content_root.set_int_member("kick", _kick);
content_root.set_int_member("redact", _redact);
content_root.set_int_member("state_default", _state_default);
content_root.set_int_member("events_default", _events_default);
var user_obj = new Json.Object();
var user_node = new Json.Node(Json.NodeType.OBJECT);
user_node.set_object(user_obj);
_user_levels.foreach(
(key, value) => {
user_obj.set_int_member(key, value);
});
content_root.set_member("users", user_node);
var events_obj = new Json.Object();
var events_node = new Json.Node(Json.NodeType.OBJECT);
events_node.set_object(events_obj);
_event_levels.foreach(
(key, value) => {
events_obj.set_int_member(key, value);
});
content_root.set_member("users", events_node);
base.to_json(json_data);
}
public void
set_user_level(string user_id, int level)
{
_user_levels[user_id] = level;
}
public void
set_event_level(string event_type, int level)
{
_event_levels[event_type] = level;
}
}

View File

@@ -0,0 +1,284 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-redaction.h"
#include "matrix-enumtypes.h"
/**
* SECTION:matrix-event-room-redaction
* @short_description: event to designate event redactions
*
* This is the default event handler for `m.room.redaction` events.
*
* Events can be redacted by either room or server admins. Redacting an event means that all
* keys not required by the protocol are stripped off, allowing admins to remove offensive or
* illegal content that may have been attached to any event. This cannot be undone, allowing
* server owners to physically delete the offending data. There is also a concept of a
* moderator hiding a message event, which can be undone, but cannot be applied to state events.
* The event that has been redacted is specified in the `redacts` event level key.
*/
enum {
PROP_0,
PROP_REASON,
PROP_REDACTED_EVENT_ID,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_redaction_properties[NUM_PROPERTIES];
typedef struct {
gchar* _reason;
gchar* _redacted_event_id;
} MatrixEventRoomRedactionPrivate;
/**
* MatrixEventRoomRedaction:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomRedaction, matrix_event_room_redaction, MATRIX_EVENT_TYPE_ROOM);
static void
matrix_event_room_redaction_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomRedactionPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_redaction_get_instance_private(MATRIX_EVENT_ROOM_REDACTION(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "reason")) != NULL) {
g_free(priv->_reason);
priv->_reason = g_strdup(json_node_get_string(node));
}
if ((node = json_object_get_member(root, "redacts")) != NULL) {
g_free(priv->_redacted_event_id);
priv->_redacted_event_id = g_strdup(json_node_get_string(node));
} else {
g_warning("redacts is missing from a m.room.redaction event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_redaction_parent_class)->from_json(matrix_event_base, json_data, error);
}
static void
matrix_event_room_redaction_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomRedactionPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
g_return_if_fail (json_data != NULL);
priv = matrix_event_room_redaction_get_instance_private(MATRIX_EVENT_ROOM_REDACTION(matrix_event_base));
root = json_node_get_object(json_data);
if (priv->_redacted_event_id == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.redaction event without /* TODO: */he redacts field");
return;
}
json_object_set_string_member(root, "redacts", priv->_redacted_event_id);
if (priv->_reason != NULL) {
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
json_object_set_string_member(content_root, "reason", priv->_reason);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_redaction_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomRedaction *
matrix_event_room_redaction_construct(GType object_type)
{
return (MatrixEventRoomRedaction *)matrix_event_room_construct(object_type);
}
/**
* matrix_event_room_redaction_new:
*
* Create a new #MatrixEventRoomRedaction object.
*
* Returns: (transfer full): a new #MatrixEventRoomRedaction object
*/
MatrixEventRoomRedaction *
matrix_event_room_redaction_new(void)
{
return matrix_event_room_redaction_construct(MATRIX_EVENT_TYPE_ROOM_REDACTION);
}
const gchar *
matrix_event_room_redaction_get_reason(MatrixEventRoomRedaction *matrix_event_room_redaction)
{
MatrixEventRoomRedactionPrivate *priv;
g_return_val_if_fail(matrix_event_room_redaction != NULL, NULL);
priv = matrix_event_room_redaction_get_instance_private(matrix_event_room_redaction);
return priv->_reason;
}
void
matrix_event_room_redaction_set_reason(MatrixEventRoomRedaction *matrix_event_room_redaction, const gchar *reason)
{
MatrixEventRoomRedactionPrivate *priv;
g_return_if_fail(matrix_event_room_redaction != NULL);
priv = matrix_event_room_redaction_get_instance_private(matrix_event_room_redaction);
if (g_strcmp0(reason, priv->_reason) != 0) {
g_free(priv->_reason);
priv->_reason = g_strdup(reason);
g_object_notify_by_pspec((GObject *)matrix_event_room_redaction, matrix_event_room_redaction_properties[PROP_REASON]);
}
}
const gchar *
matrix_event_room_redaction_get_redacted_event_id(MatrixEventRoomRedaction *matrix_event_room_redaction)
{
MatrixEventRoomRedactionPrivate *priv;
g_return_val_if_fail(matrix_event_room_redaction != NULL, NULL);
priv = matrix_event_room_redaction_get_instance_private(matrix_event_room_redaction);
return priv->_redacted_event_id;
}
void
matrix_event_room_redaction_set_redacted_event_id(MatrixEventRoomRedaction *matrix_event_room_redaction, const gchar *redacted_event_id)
{
MatrixEventRoomRedactionPrivate *priv;
g_return_if_fail(matrix_event_room_redaction != NULL);
priv = matrix_event_room_redaction_get_instance_private(matrix_event_room_redaction);
if (g_strcmp0(redacted_event_id, priv->_redacted_event_id) != 0) {
g_free(priv->_redacted_event_id);
priv->_redacted_event_id = g_strdup(redacted_event_id);
g_object_notify_by_pspec((GObject *)matrix_event_room_redaction, matrix_event_room_redaction_properties[PROP_REDACTED_EVENT_ID]);
}
}
static void
matrix_event_room_redaction_finalize(GObject *gobject)
{
MatrixEventRoomRedactionPrivate *priv = matrix_event_room_redaction_get_instance_private(MATRIX_EVENT_ROOM_REDACTION(gobject));
g_free(priv->_reason);
g_free(priv->_redacted_event_id);
G_OBJECT_CLASS(matrix_event_room_redaction_parent_class)->finalize(gobject);
}
static void
matrix_event_room_redaction_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomRedaction *matrix_event_room_redaction = MATRIX_EVENT_ROOM_REDACTION(gobject);
switch (property_id) {
case PROP_REASON:
g_value_set_string(value, matrix_event_room_redaction_get_reason(matrix_event_room_redaction));
break;
case PROP_REDACTED_EVENT_ID:
g_value_set_string(value, matrix_event_room_redaction_get_redacted_event_id(matrix_event_room_redaction));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_redaction_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomRedaction *matrix_event_room_redaction = MATRIX_EVENT_ROOM_REDACTION(gobject);
switch (property_id) {
case PROP_REASON:
matrix_event_room_redaction_set_reason(matrix_event_room_redaction, g_value_get_string(value));
break;
case PROP_REDACTED_EVENT_ID:
matrix_event_room_redaction_set_redacted_event_id(matrix_event_room_redaction, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_redaction_class_init(MatrixEventRoomRedactionClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_redaction_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_redaction_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_redaction_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_redaction_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_redaction_finalize;
/**
* MatrixEventRoomRedaction:reason:
*
* The reason for the redaction, if any.
*/
matrix_event_room_redaction_properties[PROP_REASON] = g_param_spec_string(
"reason", "reason", "reason",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_REASON, matrix_event_room_redaction_properties[PROP_REASON]);
/**
* MatrixEventRoomRedaction:redacted-event-id:
*
* The event ID that was redacted.
*/
matrix_event_room_redaction_properties[PROP_REDACTED_EVENT_ID] = g_param_spec_string(
"redacted-event-id", "redacted-event-id", "redacted-event-id",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_REDACTED_EVENT_ID, matrix_event_room_redaction_properties[PROP_REDACTED_EVENT_ID]);
}
static void
matrix_event_room_redaction_init(MatrixEventRoomRedaction *matrix_event_room_redaction) {
MatrixEventRoomRedactionPrivate *priv = matrix_event_room_redaction_get_instance_private(matrix_event_room_redaction);
priv->_reason = NULL;
priv->_redacted_event_id = NULL;
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_REDACTION_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_REDACTION_H__
# include <glib-object.h>
# include "matrix-event-room-base.h"
G_BEGIN_DECLS
#define MATRIX_EVENT_TYPE_ROOM_REDACTION (matrix_event_room_redaction_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomRedaction, matrix_event_room_redaction, MATRIX_EVENT, ROOM_REDACTION, MatrixEventRoom);
struct _MatrixEventRoomRedactionClass {
MatrixEventRoomClass parent_class;
};
MatrixEventRoomRedaction* matrix_event_room_redaction_new (void);
MatrixEventRoomRedaction* matrix_event_room_redaction_construct (GType object_type);
const gchar* matrix_event_room_redaction_get_reason (MatrixEventRoomRedaction* self);
void matrix_event_room_redaction_set_reason (MatrixEventRoomRedaction* self, const gchar* value);
const gchar* matrix_event_room_redaction_get_redacted_event_id (MatrixEventRoomRedaction* self);
void matrix_event_room_redaction_set_redacted_event_id (MatrixEventRoomRedaction* self, const gchar* value);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_REDACTION_H__ */

View File

@@ -1,85 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.redaction event
*
* Events can be redacted by either room or server admins. Redacting
* an event means that all keys not required by the protocol are
* stripped off, allowing admins to remove offensive or illegal
* content that may have been attached to any event. This cannot be
* undone, allowing server owners to physically delete the offending
* data. There is also a concept of a moderator hiding a message
* event, which can be undone, but cannot be applied to state
* events. The event that has been redacted is specified in the
* redacts event level key.
*/
public class Matrix.Event.RoomRedaction : Matrix.Event.Room {
/**
* The reason for the redaction, if any.
*/
public string? reason { get; set; default = null; }
/**
* The event ID that was redacted.
*/
public string? redacted_event_id { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("reason")) != null) {
_reason = node.get_string();
}
if ((node = root.get_member("redacts")) != null) {
_redacted_event_id = node.get_string();
} else {
warning("redacts is missing from a m.room.redaction event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_redacted_event_id == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.redaction event without the redacts field");
}
var root = json_data.get_object();
root.set_string_member("redacts", _redacted_event_id);
if (_reason != null) {
var content_root = root.get_member("content").get_object();
content_root.set_string_member("reason", _reason);
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,588 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-third-party-invite.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-third-party-invite
* @short_description: event to hold 3rd party invites
*
* This is the default event handler for `m.room.third_party_invite` events.
*
* Acts as an `m.room.member` invite event (see #MatrixEventRoomMember), where there isnt a
* target Matrix ID to invite. This event contains a token and a public key whose private key
* must be used to sign the token. Any user who can present that signature may use this
* invitation to join the target room.
*/
struct _MatrixThirdPartyInvitePublicKey {
gchar* key;
gchar* validity_url;
guint refcount;
};
/**
* MatrixThirdPartyInvitePublicKey:
*/
G_DEFINE_BOXED_TYPE(MatrixThirdPartyInvitePublicKey, matrix_third_party_invite_public_key, (GBoxedCopyFunc)matrix_third_party_invite_public_key_ref, (GBoxedFreeFunc)matrix_third_party_invite_public_key_unref);
MatrixThirdPartyInvitePublicKey *
matrix_third_party_invite_public_key_new(void)
{
MatrixThirdPartyInvitePublicKey *ret = g_new0(MatrixThirdPartyInvitePublicKey, 1);
ret->refcount = 1;
return ret;
}
MatrixThirdPartyInvitePublicKey *
matrix_third_party_invite_public_key_ref(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key)
{
g_return_val_if_fail(matrix_third_party_invite_public_key != NULL, NULL);
++matrix_third_party_invite_public_key->refcount;
return matrix_third_party_invite_public_key;
}
void
matrix_third_party_invite_public_key_unref(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key)
{
g_return_if_fail(matrix_third_party_invite_public_key != NULL);
if (--(matrix_third_party_invite_public_key->refcount) == 0) {
g_free(matrix_third_party_invite_public_key->key);
g_free(matrix_third_party_invite_public_key->validity_url);
g_free(matrix_third_party_invite_public_key);
}
}
/**
* matrix_third_party_invite_public_key_get_key:
* @third_party_invite_public_key: a #MatrixThirdPartyInvitePublicKey
*
* Get the public key from the 3rd party invite.
*
* Returns: (nullable) (transfer none): the public key
*/
const gchar *
matrix_third_party_invite_public_key_get_key(MatrixThirdPartyInvitePublicKey *third_party_invite_public_key)
{
g_return_val_if_fail(third_party_invite_public_key != NULL, NULL);
return third_party_invite_public_key->key;
}
void
matrix_third_party_invite_public_key_set_key(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key, const gchar *key)
{
g_return_if_fail(matrix_third_party_invite_public_key != NULL);
g_free(matrix_third_party_invite_public_key->key);
matrix_third_party_invite_public_key->key = g_strdup(key);
}
const gchar *
matrix_third_party_invite_public_key_get_validity_url(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key)
{
g_return_val_if_fail(matrix_third_party_invite_public_key != NULL, NULL);
return matrix_third_party_invite_public_key->validity_url;
}
void
matrix_third_party_invite_public_key_set_validity_url(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key, const gchar *validity_url)
{
g_return_if_fail(matrix_third_party_invite_public_key != NULL);
g_free(matrix_third_party_invite_public_key->validity_url);
matrix_third_party_invite_public_key->validity_url = g_strdup(validity_url);
}
enum {
PROP_0,
PROP_DISPLAY_NAME,
PROP_KEY_VALIDITY_URL,
PROP_PUBLIC_KEY,
PROP_TOKEN,
NUM_PROPERTIES
};
static GParamSpec *matrix_event_room_third_party_invite_properties[NUM_PROPERTIES];
typedef struct {
gchar* _display_name;
gchar* _key_validity_url;
gchar* _public_key;
MatrixThirdPartyInvitePublicKey **_public_keys;
gint _public_keys_len;
} MatrixEventRoomThirdPartyInvitePrivate;
/**
* MatrixEventRoomThirdPartyInvite:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomThirdPartyInvite, matrix_event_room_third_party_invite, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_third_party_invite_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
priv = matrix_event_room_third_party_invite_get_instance_private(MATRIX_EVENT_ROOM_THIRD_PARTY_INVITE(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "display_name")) != NULL) {
g_free(priv->_display_name);
priv->_display_name = g_strdup(json_node_get_string(node));
} else {
g_warning("content.display_name is missing from a m.room.third_party_invite event");
}
if ((node = json_object_get_member(content_root, "public_key")) != NULL) {
g_free(priv->_public_key);
priv->_public_key = g_strdup(json_node_get_string(node));
} else {
g_warning("content.public_key is missing from a m.room.third_party_invite event");
}
if ((node = json_object_get_member(content_root, "key_validity_url")) != NULL) {
g_free(priv->_key_validity_url);
priv->_key_validity_url = g_strdup(json_node_get_string(node));
} else {
g_warning("content.key_validity_url is missing from a m.room.third_party_invite event");
}
if ((node = json_object_get_member(content_root, "public_keys")) != NULL) {
JsonArray *public_key_list = json_node_get_array(node);
priv->_public_keys_len = json_array_get_length(public_key_list);
priv->_public_keys = g_new0(MatrixThirdPartyInvitePublicKey *, priv->_public_keys_len);
for (gint i = 0; i < priv->_public_keys_len; i++) {
JsonNode *member_node = json_array_get_element(public_key_list, i);
JsonObject *member_root = json_node_get_object(member_node);
priv->_public_keys[i] = matrix_third_party_invite_public_key_new();
if ((node = json_object_get_member(member_root, "public_key")) != NULL) {
priv->_public_keys[i]->key = g_strdup(json_node_get_string(node));
} else {
g_warning("content.public_keys[].public_key is missing from an m.room.third_party_invite event");
}
if ((node = json_object_get_member(member_root, "validity_url")) != NULL) {
priv->_public_keys[i]->validity_url = g_strdup(json_node_get_string(node));
} else {
g_warning("content.public_keys[].validity_url is missing from an m.room.third_party_invite event");
}
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_third_party_invite_parent_class)->from_json((MatrixEventBase*)matrix_event_base, json_data, error);
}
static void
matrix_event_room_third_party_invite_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonArray *key_list;
JsonNode *content_node;
priv = matrix_event_room_third_party_invite_get_instance_private(MATRIX_EVENT_ROOM_THIRD_PARTY_INVITE(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if (priv->_display_name == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.third_party_invite event without display_name");
return;
}
if (priv->_public_key == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.third_party_invite without public_key");
return;
}
if (priv->_key_validity_url == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.third_party_invite without key_validity_url");
return;
}
json_object_set_string_member(content_root, "display_name", priv->_display_name);
json_object_set_string_member(content_root, "public_key", priv->_public_key);
json_object_set_string_member(content_root, "key_validity_url", priv->_key_validity_url);
key_list = json_array_new();
for (gint i = 0; i < priv->_public_keys_len; i++) {
JsonObject *key_root;
JsonNode *key_node;
MatrixThirdPartyInvitePublicKey *entry = priv->_public_keys[i];
if (entry->key == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.third_party_invite with a missing key under public_keys");
return;
}
key_root = json_object_new();
key_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(key_node, key_root);
json_object_set_string_member(key_root, "public_key", entry->key);
if (entry->validity_url != NULL) {
json_object_set_string_member(key_root, "key_validity_url", entry->validity_url);
}
json_array_add_element(key_list, key_node);
}
if (json_array_get_length(key_list) > 0) {
JsonNode *keys_node = json_node_new(JSON_NODE_ARRAY);
json_node_set_array(keys_node, key_list);
json_object_set_member(content_root, "public_keys", keys_node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_third_party_invite_parent_class)->to_json(matrix_event_base, json_data, error);
}
MatrixEventRoomThirdPartyInvite *
matrix_event_room_third_party_invite_construct(GType object_type)
{
return (MatrixEventRoomThirdPartyInvite *)matrix_event_state_construct(object_type);
}
MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite_new(void)
{
return matrix_event_room_third_party_invite_construct(MATRIX_EVENT_TYPE_ROOM_THIRD_PARTY_INVITE);
}
const gchar *
matrix_event_room_third_party_invite_get_display_name(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_val_if_fail(matrix_event_room_third_party_invite != NULL, NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
return priv->_display_name;
}
void
matrix_event_room_third_party_invite_set_display_name(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, const gchar *display_name)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_if_fail(matrix_event_room_third_party_invite != NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
if (g_strcmp0(display_name, priv->_display_name) != 0) {
g_free(priv->_display_name);
priv->_display_name = g_strdup(display_name);
g_object_notify_by_pspec((GObject *)matrix_event_room_third_party_invite, matrix_event_room_third_party_invite_properties[PROP_DISPLAY_NAME]);
}
}
const gchar *
matrix_event_room_third_party_invite_get_key_validity_url(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_val_if_fail(matrix_event_room_third_party_invite != NULL, NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
return priv->_key_validity_url;
}
void
matrix_event_room_third_party_invite_set_key_validity_url(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, const gchar *key_validity_url)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_if_fail(matrix_event_room_third_party_invite != NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
if (g_strcmp0(key_validity_url, priv->_key_validity_url) != 0) {
g_free(priv->_key_validity_url);
priv->_key_validity_url = g_strdup(key_validity_url);
g_object_notify_by_pspec((GObject *)matrix_event_room_third_party_invite, matrix_event_room_third_party_invite_properties[PROP_KEY_VALIDITY_URL]);
}
}
const gchar *
matrix_event_room_third_party_invite_get_public_key(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_val_if_fail(matrix_event_room_third_party_invite != NULL, NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
return priv->_public_key;
}
void
matrix_event_room_third_party_invite_set_public_key(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, const gchar *public_key)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_if_fail(matrix_event_room_third_party_invite != NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
if (g_strcmp0(public_key, priv->_public_key) != 0) {
g_free(priv->_public_key);
priv->_public_key = g_strdup(public_key);
g_object_notify_by_pspec((GObject *)matrix_event_room_third_party_invite, matrix_event_room_third_party_invite_properties[PROP_PUBLIC_KEY]);
}
}
const MatrixThirdPartyInvitePublicKey **
matrix_event_room_third_party_invite_get_public_keys(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, int *n_public_keys)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_val_if_fail(matrix_event_room_third_party_invite != NULL, NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
if (n_public_keys != NULL) {
*n_public_keys = priv->_public_keys_len;
}
return (const MatrixThirdPartyInvitePublicKey **)priv->_public_keys;
}
void
matrix_event_room_third_party_invite_set_public_keys(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, MatrixThirdPartyInvitePublicKey **public_keys, int n_public_keys)
{
MatrixEventRoomThirdPartyInvitePrivate *priv;
g_return_if_fail(matrix_event_room_third_party_invite != NULL);
priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
for (gint i = 0; i < priv->_public_keys_len; i++) {
matrix_third_party_invite_public_key_unref(priv->_public_keys[i]);
}
g_free(priv->_public_keys);
priv->_public_keys = g_new0(MatrixThirdPartyInvitePublicKey *, n_public_keys);
for (gint i = 0; i < n_public_keys; i++) {
priv->_public_keys[i] = matrix_third_party_invite_public_key_ref(public_keys[i]);
}
priv->_public_keys_len = n_public_keys;
}
const gchar *
matrix_event_room_third_party_invite_get_token(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite)
{
g_return_val_if_fail(matrix_event_room_third_party_invite != NULL, NULL);
return matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_room_third_party_invite));
}
void
matrix_event_room_third_party_invite_set_token(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, const gchar *token)
{
const gchar *state_key;
g_return_if_fail(matrix_event_room_third_party_invite != NULL);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_room_third_party_invite));
if (g_strcmp0(token, state_key) != 0) {
matrix_event_state_set_state_key(MATRIX_EVENT_STATE(matrix_event_room_third_party_invite), token);
g_object_notify_by_pspec ((GObject *) matrix_event_room_third_party_invite, matrix_event_room_third_party_invite_properties[PROP_TOKEN]);
}
}
static void
matrix_event_room_third_party_invite_finalize(GObject *gobject)
{
MatrixEventRoomThirdPartyInvitePrivate *priv = matrix_event_room_third_party_invite_get_instance_private(MATRIX_EVENT_ROOM_THIRD_PARTY_INVITE(gobject));
g_free(priv->_display_name);
g_free(priv->_key_validity_url);
g_free(priv->_public_key);
for (gint i = 0; i < priv->_public_keys_len; i++) {
matrix_third_party_invite_public_key_unref(priv->_public_keys[i]);
}
g_free(priv->_public_keys);
G_OBJECT_CLASS (matrix_event_room_third_party_invite_parent_class)->finalize(gobject);
}
static void
matrix_event_room_third_party_invite_get_property(GObject *gobject, guint property_id, GValue *value, GParamSpec *pspec)
{
MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite = MATRIX_EVENT_ROOM_THIRD_PARTY_INVITE(gobject);
switch (property_id) {
case PROP_DISPLAY_NAME:
g_value_set_string(value, matrix_event_room_third_party_invite_get_display_name(matrix_event_room_third_party_invite));
break;
case PROP_KEY_VALIDITY_URL:
g_value_set_string(value, matrix_event_room_third_party_invite_get_key_validity_url(matrix_event_room_third_party_invite));
break;
case PROP_PUBLIC_KEY:
g_value_set_string(value, matrix_event_room_third_party_invite_get_public_key(matrix_event_room_third_party_invite));
break;
case PROP_TOKEN:
g_value_set_string(value, matrix_event_room_third_party_invite_get_token(matrix_event_room_third_party_invite));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_third_party_invite_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec) {
MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite = MATRIX_EVENT_ROOM_THIRD_PARTY_INVITE(gobject);
switch(property_id) {
case PROP_DISPLAY_NAME:
matrix_event_room_third_party_invite_set_display_name(matrix_event_room_third_party_invite, g_value_get_string(value));
break;
case PROP_KEY_VALIDITY_URL:
matrix_event_room_third_party_invite_set_key_validity_url(matrix_event_room_third_party_invite, g_value_get_string(value));
break;
case PROP_PUBLIC_KEY:
matrix_event_room_third_party_invite_set_public_key(matrix_event_room_third_party_invite, g_value_get_string(value));
break;
case PROP_TOKEN:
matrix_event_room_third_party_invite_set_token(matrix_event_room_third_party_invite, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_third_party_invite_class_init(MatrixEventRoomThirdPartyInviteClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_third_party_invite_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_third_party_invite_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_room_third_party_invite_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_room_third_party_invite_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_room_third_party_invite_finalize;
/**
* MatrixEventRoomThirdPartyInvite:display-name:
*
* A user-readable string which represents the user who has been
* invited. This should not contain the user's third party ID, as
* otherwise when the invite is accepted it would leak the
* association between the matrix ID and the third party ID.
*/
matrix_event_room_third_party_invite_properties[PROP_DISPLAY_NAME] = g_param_spec_string(
"display-name", "display-name", "display-name",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_DISPLAY_NAME, matrix_event_room_third_party_invite_properties[PROP_DISPLAY_NAME]);
/**
* MatrixEventRoomThirdPartyInvite:key-validity-url:
*
* A URL which can be fetched, with querystring
* public_key=public_key, to validate whether the key has been
* revoked. The URL must return a JSON object containing a boolean
* property named valid.
*/
matrix_event_room_third_party_invite_properties[PROP_KEY_VALIDITY_URL] = g_param_spec_string(
"key-validity-url", "key-validity-url", "key-validity-url",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_KEY_VALIDITY_URL, matrix_event_room_third_party_invite_properties[PROP_KEY_VALIDITY_URL]);
/**
* MatrixEventRoomThirdPartyInvite:public-key:
*
* A base64-encoded ed25519 key with which token must be signed
* (though a signature from any entry in public_keys is also
* sufficient). This exists for backwards compatibility.
*/
matrix_event_room_third_party_invite_properties[PROP_PUBLIC_KEY] = g_param_spec_string(
"public-key", "public-key", "public-key",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_PUBLIC_KEY, matrix_event_room_third_party_invite_properties[PROP_PUBLIC_KEY]);
/**
* MatrixEventRoomThirdPartyInvite:token:
*
* The token, of which a signature must be produced in order to
* join the room.
*/
matrix_event_room_third_party_invite_properties[PROP_TOKEN] = g_param_spec_string(
"token", "token", "token",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TOKEN, matrix_event_room_third_party_invite_properties[PROP_TOKEN]);
}
static void
matrix_event_room_third_party_invite_init(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite)
{
MatrixEventRoomThirdPartyInvitePrivate *priv = matrix_event_room_third_party_invite_get_instance_private(matrix_event_room_third_party_invite);
priv->_display_name = NULL;
priv->_key_validity_url = NULL;
priv->_public_key = NULL;
}

View File

@@ -0,0 +1,59 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_THIRD_PARTY_INVITE_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_THIRD_PARTY_INVITE_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
typedef struct _MatrixThirdPartyInvitePublicKey MatrixThirdPartyInvitePublicKey;
GType matrix_third_party_invite_public_key_get_type(void) G_GNUC_CONST;
# define MATRIX_TYPE_THIRD_PARTY_INVITE_PUBLIC_KEY (matrix_third_party_invite_public_key_get_type())
MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key_new(void);
MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key_ref(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key);
void matrix_third_party_invite_public_key_unref(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key);
const gchar *matrix_third_party_invite_public_key_get_key(MatrixThirdPartyInvitePublicKey *third_party_invite_public_key);
void matrix_third_party_invite_public_key_set_key(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key, const gchar *key);
const gchar *matrix_third_party_invite_public_key_get_validity_url(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key);
void matrix_third_party_invite_public_key_set_validity_url(MatrixThirdPartyInvitePublicKey *matrix_third_party_invite_public_key, const gchar *validity_url);
#define MATRIX_EVENT_TYPE_ROOM_THIRD_PARTY_INVITE (matrix_event_room_third_party_invite_get_type ())
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomThirdPartyInvite, matrix_event_room_third_party_invite, MATRIX_EVENT, ROOM_THIRD_PARTY_INVITE, MatrixEventState);
struct _MatrixEventRoomThirdPartyInviteClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomThirdPartyInvite* matrix_event_room_third_party_invite_new (void);
MatrixEventRoomThirdPartyInvite* matrix_event_room_third_party_invite_construct (GType object_type);
const gchar* matrix_event_room_third_party_invite_get_display_name (MatrixEventRoomThirdPartyInvite* self);
void matrix_event_room_third_party_invite_set_display_name (MatrixEventRoomThirdPartyInvite* self, const gchar* value);
const gchar* matrix_event_room_third_party_invite_get_key_validity_url (MatrixEventRoomThirdPartyInvite* self);
void matrix_event_room_third_party_invite_set_key_validity_url (MatrixEventRoomThirdPartyInvite* self, const gchar* value);
const gchar* matrix_event_room_third_party_invite_get_public_key (MatrixEventRoomThirdPartyInvite* self);
void matrix_event_room_third_party_invite_set_public_key (MatrixEventRoomThirdPartyInvite* self, const gchar* value);
const MatrixThirdPartyInvitePublicKey **matrix_event_room_third_party_invite_get_public_keys(MatrixEventRoomThirdPartyInvite *matrix_event_room_third_party_invite, int *n_public_keys);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_THIRD_PARTY_INVITE_H__ */

View File

@@ -1,177 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Class to hold a m.room.third_party_invite event
*
* Acts as an m.room.member invite event, where there isn't a target
* user_id to invite. This event contains a token and a public key
* whose private key must be used to sign the token. Any user who can
* present that signature may use this invitation to join the target
* room.
*/
public class Matrix.Event.RoomThirdPartyInvite : Matrix.Event.State {
public struct PublicKey {
string? key;
string? validity_url;
}
/**
* A user-readable string which represents the user who has been
* invited. This should not contain the user's third party ID, as
* otherwise when the invite is accepted it would leak the
* association between the matrix ID and the third party ID.
*/
public string? display_name { get; set; default = null; }
/**
* A URL which can be fetched, with querystring
* public_key=public_key, to validate whether the key has been
* revoked. The URL must return a JSON object containing a boolean
* property named valid.
*/
public string? key_validity_url { get; set; default = null; }
/**
* A base64-encoded ed25519 key with which token must be signed
* (though a signature from any entry in public_keys is also
* sufficient). This exists for backwards compatibility.
*/
public string? public_key { get; set; default = null;}
/**
* Keys with which the token may be signed.
*/
public PublicKey[] public_keys { get; set; }
/**
* The token, of which a signature must be produced in order to
* join the room.
*/
public string? token {
get {
return _state_key;
}
set {
_state_key = value;
}
default = null;
}
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node;
if ((node = root.get_member("state_key")) != null) {
_state_key = node.get_string();
} else if (Config.DEBUG) {
warning("state_key is missing from a m.room.third_party_invite_event");
}
if ((node = content_root.get_member("display_name")) != null) {
_display_name = node.get_string();
} else {
warning("content.display_name is missing from a m.room.third_party_invite event");
}
if ((node = content_root.get_member("public_key")) != null) {
_public_key = node.get_string();
} else {
warning("content.public_key is missing from a m.room.third_party_invite event");
}
if ((node = content_root.get_member("key_validity_url")) != null) {
_key_validity_url = node.get_string();
} else {
warning("content.key_validity_url is missing from a m.room.third_party_invite event");
}
if ((node = content_root.get_member("public_keys")) != null) {
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_display_name == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.third_party_invite event without display_name");
}
if (_public_key == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.third_party_invite without public_key");
}
if (_key_validity_url == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.third_party_invite without key_validity_url");
}
if (_state_key == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.third_party_invite without token");
}
var content_root = json_data.get_object()
.get_member("content").get_object();
// We don't need to set the state key here, our base class
// will do it for us
content_root.set_string_member("display_name", _display_name);
content_root.set_string_member("public_key", _public_key);
content_root.set_string_member("key_validity_url", _key_validity_url);
var key_list = new Json.Array();
foreach (var entry in _public_keys) {
if (entry.key == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.third_party_invite with a missing key under public_keys");
}
var key_obj = new Json.Object();
var key_node = new Json.Node(Json.NodeType.OBJECT);
key_node.set_object(key_obj);
key_obj.set_string_member("public_key", entry.key);
if (entry.validity_url != null) {
key_obj.set_string_member("key_validity_url", entry.validity_url);
}
key_list.add_element(key_node);
}
if (key_list.get_length() > 0) {
var keys_node = new Json.Node(Json.NodeType.ARRAY);
keys_node.set_array(key_list);
content_root.set_member("public_keys", keys_node);
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,240 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-room-topic.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-room-topic
* @short_description: event to hold a room topic
*
* This is the default event handler for `m.room.topic` events.
*
* A topic is a short message detailing what is currently being discussed in the room. It can
* also be used as a way to display extra information about the room, which may not be
* suitable for the room name.
*/
enum {
PROP_0,
PROP_TOPIC,
NUM_PROPS
};
static GParamSpec *matrix_event_room_topic_properties[NUM_PROPS];
typedef struct {
gchar* _topic;
} MatrixEventRoomTopicPrivate;
/**
* MatrixEventRoomTopic:
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventRoomTopic, matrix_event_room_topic, MATRIX_EVENT_TYPE_STATE);
static void
matrix_event_room_topic_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomTopicPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_topic_get_instance_private(MATRIX_EVENT_ROOM_TOPIC(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if (DEBUG && ((node = json_object_get_member(root, "state_key")) != NULL)) {
const gchar *state_key = json_node_get_string(node);
if ((state_key == NULL) || (*state_key == 0)) {
g_warning("state_key of a m.room.topic event is non-empty");
}
}
if ((node = json_object_get_member(content_root, "topic")) != NULL) {
g_free(priv->_topic);
priv->_topic = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning("content.topic is missing from an m.room.topic event");
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_topic_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_room_topic_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventRoomTopicPrivate *priv;
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
GError *inner_error = NULL;
const gchar *state_key;
g_return_if_fail(json_data != NULL);
priv = matrix_event_room_topic_get_instance_private(MATRIX_EVENT_ROOM_TOPIC(matrix_event_base));
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
state_key = matrix_event_state_get_state_key(MATRIX_EVENT_STATE(matrix_event_base));
if ((state_key == NULL) || (*state_key == 0)) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate a m.room.topic event with a non-empty state_key");
return;
}
if (priv->_topic != NULL) {
json_object_set_string_member(content_root, "topic", priv->_topic);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_room_topic_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
MatrixEventRoomTopic *
matrix_event_room_topic_construct(GType object_type)
{
return (MatrixEventRoomTopic *)matrix_event_state_construct(object_type);
}
MatrixEventRoomTopic *
matrix_event_room_topic_new(void) {
return matrix_event_room_topic_construct(MATRIX_EVENT_TYPE_ROOM_TOPIC);
}
const gchar *
matrix_event_room_topic_get_topic(MatrixEventRoomTopic *matrix_event_room_topic)
{
MatrixEventRoomTopicPrivate *priv;
g_return_val_if_fail(matrix_event_room_topic != NULL, NULL);
priv = matrix_event_room_topic_get_instance_private(matrix_event_room_topic);
return priv->_topic;
}
void
matrix_event_room_topic_set_topic(MatrixEventRoomTopic *matrix_event_room_topic, const gchar *topic)
{
MatrixEventRoomTopicPrivate *priv;
g_return_if_fail(matrix_event_room_topic != NULL);
priv = matrix_event_room_topic_get_instance_private(matrix_event_room_topic);
if (g_strcmp0(topic, priv->_topic) != 0) {
g_free(priv->_topic);
priv->_topic = g_strdup(topic);
g_object_notify_by_pspec((GObject *)matrix_event_room_topic, matrix_event_room_topic_properties[PROP_TOPIC]);
}
}
static void
matrix_event_room_topic_finalize(GObject *gobject)
{
MatrixEventRoomTopicPrivate *priv;
priv = matrix_event_room_topic_get_instance_private(MATRIX_EVENT_ROOM_TOPIC(gobject));
g_free(priv->_topic);
G_OBJECT_CLASS(matrix_event_room_topic_parent_class)->finalize(gobject);
}
static void
matrix_event_room_topic_get_property(GObject *gobject, guint property_id, GValue* value, GParamSpec* pspec)
{
MatrixEventRoomTopicPrivate *priv = matrix_event_room_topic_get_instance_private(MATRIX_EVENT_ROOM_TOPIC(gobject));
switch (property_id) {
case PROP_TOPIC:
g_value_set_string(value, priv->_topic);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_topic_set_property(GObject *gobject, guint property_id, const GValue *value, GParamSpec *pspec)
{
MatrixEventRoomTopic *matrix_event_room_topic = MATRIX_EVENT_ROOM_TOPIC(gobject);
switch (property_id) {
case PROP_TOPIC:
matrix_event_room_topic_set_topic(matrix_event_room_topic, g_value_get_string(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_room_topic_class_init(MatrixEventRoomTopicClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_room_topic_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_room_topic_real_to_json;
G_OBJECT_CLASS (klass)->get_property = matrix_event_room_topic_get_property;
G_OBJECT_CLASS (klass)->set_property = matrix_event_room_topic_set_property;
G_OBJECT_CLASS (klass)->finalize = matrix_event_room_topic_finalize;
/**
* MatrixEventRoomTopic:topic:
*
* The topic text.
*/
matrix_event_room_topic_properties[PROP_TOPIC] = g_param_spec_string(
"topic", "topic", "topic",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_TOPIC, matrix_event_room_topic_properties[PROP_TOPIC]);
}
static void
matrix_event_room_topic_init(MatrixEventRoomTopic *matrix_event_room_topic)
{
MatrixEventRoomTopicPrivate *priv;
priv = matrix_event_room_topic_get_instance_private(matrix_event_room_topic);
priv->_topic = NULL;
}

View File

@@ -0,0 +1,41 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_ROOM_TOPIC_H__
# define __MATRIX_GLIB_SDK_EVENT_ROOM_TOPIC_H__
# include <glib-object.h>
# include "matrix-event-state-base.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_ROOM_TOPIC matrix_event_room_topic_get_type ()
G_DECLARE_DERIVABLE_TYPE(MatrixEventRoomTopic, matrix_event_room_topic, MATRIX_EVENT, ROOM_TOPIC, MatrixEventState);
struct _MatrixEventRoomTopicClass {
MatrixEventStateClass parent_class;
};
MatrixEventRoomTopic* matrix_event_room_topic_new (void);
MatrixEventRoomTopic* matrix_event_room_topic_construct (GType object_type);
const gchar* matrix_event_room_topic_get_topic (MatrixEventRoomTopic* self);
void matrix_event_room_topic_set_topic (MatrixEventRoomTopic* self, const gchar* value);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_ROOM_TOPIC_H__ */

View File

@@ -1,74 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
/**
* Event type to hold the m.room.topic event.
*
* A topic is a short message detailing what is currently being
* discussed in the room. It can also be used as a way to display
* extra information about the room, which may not be suitable for the
* room name.
*/
public class Matrix.Event.RoomTopic : Matrix.Event.State {
/**
* The topic text.
*/
public string? topic { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
Json.Node? node = null;
if (Config.DEBUG && ((node = root.get_member("state_key")) != null)) {
if (node.get_string() != "") {
warning("state_key of a m.room.topic event is non-empty");
}
}
if ((node = content_root.get_member("topic")) != null) {
_topic = node.get_string();
} else if (Config.DEBUG) {
warning("content.topic is missing from an m.room.topic event");
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
var content_root = root.get_member("content").get_object();
if (_state_key != "") {
throw new Matrix.Error.INCOMPLETE(
"Won't generate a m.room.topic event with a non-empty state_key");
}
if (_topic != null) {
content_root.set_string_member("topic", _topic);
}
base.to_json(json_data);
}
}

View File

@@ -0,0 +1,347 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-state-base.h"
#include "matrix-enumtypes.h"
#include "config.h"
/**
* SECTION:matrix-event-state-base
* @short_description: abstract base class for state events
* @title: base class for state events
*
* #MatrixEventState is the base class for state events. State events are special room events
* with an extra `state_key` and `prev_content` event which are handled by this class.
*/
enum {
PROP_0,
PROP_STATE_KEY,
PROP_PREV_CONTENT,
NUM_PROPS
};
static GParamSpec *matrix_event_state_properties[NUM_PROPS];
typedef struct {
JsonNode *_prev_content;
gchar *_state_key;
} MatrixEventStatePrivate;
/**
* MatrixEventState:
*
* The only exposed field for such events is the state key. There are some events that may
* send the state key in a different field; handlers of such events can overwrite this
* property directly, but otherwise its descouraged.
*/
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE(MatrixEventState, matrix_event_state, MATRIX_EVENT_TYPE_ROOM);
static void
matrix_event_state_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventStatePrivate *priv;
JsonObject *root;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
priv = matrix_event_state_get_instance_private(MATRIX_EVENT_STATE(matrix_event_base));
root = json_node_get_object(json_data);
if ((node = json_object_get_member(root, "state_key")) != NULL) {
g_free(priv->_state_key);
priv->_state_key = g_strdup(json_node_get_string(node));
} else if (DEBUG) {
g_warning("state_key is not present in a State event");
}
if ((node = json_object_get_member(root, "prev_content")) != NULL) {
priv->_prev_content = node;
}
MATRIX_EVENT_BASE_CLASS(matrix_event_state_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
json_node_unref(node);
json_object_unref(root);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_state_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_node, GError **error)
{
MatrixEventState *matrix_event_state;
MatrixEventStatePrivate *priv;
JsonObject *root;
GError *inner_error = NULL;
matrix_event_state = MATRIX_EVENT_STATE(matrix_event_base);
priv = matrix_event_state_get_instance_private(matrix_event_state);
if (priv->_state_key == NULL) {
g_set_error(error, MATRIX_ERROR, MATRIX_ERROR_INCOMPLETE,
"Won't generate state events without state_key");
return;
}
root = json_node_get_object(json_node);
json_object_set_string_member(root, "state_key", priv->_state_key);
if (priv->_prev_content != NULL) {
json_object_set_member(root, "prev_content", priv->_prev_content);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_state_parent_class)->to_json(MATRIX_EVENT_BASE(matrix_event_base), json_node, &inner_error);
json_object_unref(root);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
/**
* matrix_event_state_get_stripped_node:
* @event: a #MatrixEventState derived object
*
* Get a stripped state event.
*
* Returns: (transfer full) (nullable): %NULL if the event is not allowed to be stripped, or
* the full JSON node otherwise
*/
JsonNode *
matrix_event_state_get_stripped_node(MatrixEventState *matrix_event_state)
{
MatrixEventBase *matrix_event_base;
const gchar *event_type;
g_return_val_if_fail(matrix_event_state != NULL, NULL);
matrix_event_base = MATRIX_EVENT_BASE(matrix_event_state);
event_type = matrix_event_base_get_event_type(matrix_event_base);
// TODO: this may be controlled by an object property instead.
if ((g_strcmp0(event_type, "m.room.join_rules") != 0) &&
(g_strcmp0(event_type, "m.room.canonical_alias") != 0) &&
(g_strcmp0(event_type, "m.room.avatar") != 0) &&
(g_strcmp0(event_type, "m.room.name") != 0)) {
g_warning("Trying to strip down event that is not allowed to be stripped.");
return NULL;
}
return matrix_event_base_get_json(matrix_event_base);
}
MatrixEventState *
matrix_event_state_construct(GType object_type)
{
return (MatrixEventState *)matrix_event_room_construct(object_type);
}
/**
* matrix_event_state_get_state_key:
* @event: a #MatrixEventState derived object
*
* Get the state key of @event.
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the state key
*/
const gchar *
matrix_event_state_get_state_key(MatrixEventState *matrix_event_state)
{
MatrixEventStatePrivate *priv = matrix_event_state_get_instance_private(matrix_event_state);
g_return_val_if_fail(matrix_event_state != NULL, NULL);
return priv->_state_key;
}
/**
* matrix_event_state_set_state_key:
* @event: a #MatrixEventState derived object
* @state_key: a state key
*
* Set the state key of @event.
*/
void
matrix_event_state_set_state_key(MatrixEventState *matrix_event_state, const gchar *state_key)
{
MatrixEventStatePrivate *priv = matrix_event_state_get_instance_private(matrix_event_state);
g_return_if_fail(matrix_event_state != NULL);
g_free(priv->_state_key);
priv->_state_key = g_strdup(state_key);
g_object_notify_by_pspec((GObject *)matrix_event_state, matrix_event_state_properties[PROP_STATE_KEY]);
}
/**
* matrix_event_state_get_prev_content:
* @event: a #MatrixEventState derived object
*
* Get the known previous content for the state represented by @event.
*
* The value returned is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): a #JsonNode representing the last known state of @event
*/
JsonNode *
matrix_event_state_get_prev_content(MatrixEventState *matrix_event_state)
{
MatrixEventStatePrivate *priv;
g_return_val_if_fail(matrix_event_state != NULL, NULL);
priv = matrix_event_state_get_instance_private(matrix_event_state);
return priv->_prev_content;
}
/**
* matrix_event_state_set_prev_content:
* @event: a #MatrixEventState derived object
* @prev_content: (transfer none) (nullable): the last known content of the state
* represented by @event
*
* Set the last known content of the state represented by @event. This is required to prevent
* the race condition when a client tries to overwrite a state that has been changed since then.
*/
void
matrix_event_state_set_prev_content(MatrixEventState *matrix_event_state, JsonNode *prev_content)
{
MatrixEventStatePrivate *priv;
g_return_if_fail(matrix_event_state != NULL);
priv = matrix_event_state_get_instance_private(matrix_event_state);
if (priv->_prev_content != prev_content) {
json_node_unref(priv->_prev_content);
priv->_prev_content = json_node_ref(prev_content);
g_object_notify_by_pspec((GObject *)matrix_event_state, matrix_event_state_properties[PROP_PREV_CONTENT]);
}
}
static void
matrix_event_state_finalize(GObject *gobject)
{
MatrixEventState *matrix_event_state = MATRIX_EVENT_STATE(gobject);
MatrixEventStatePrivate *priv = matrix_event_state_get_instance_private(matrix_event_state);
g_free(priv->_state_key);
json_node_unref(priv->_prev_content);
G_OBJECT_CLASS(matrix_event_state_parent_class)->finalize(gobject);
}
static void
matrix_event_state_get_property(GObject *gobject, guint property_id, GValue* value, GParamSpec* pspec)
{
MatrixEventState *matrix_event_state = MATRIX_EVENT_STATE(gobject);
MatrixEventStatePrivate *priv = matrix_event_state_get_instance_private(matrix_event_state);
switch (property_id) {
case PROP_STATE_KEY:
g_value_set_string(value, priv->_state_key);
break;
case PROP_PREV_CONTENT:
g_value_set_boxed(value, priv->_prev_content);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_state_set_property(GObject *gobject, guint property_id, const GValue* value, GParamSpec* pspec)
{
MatrixEventState *matrix_event_state = MATRIX_EVENT_STATE(gobject);
switch (property_id) {
case PROP_STATE_KEY:
matrix_event_state_set_state_key(matrix_event_state, g_value_get_string(value));
break;
case PROP_PREV_CONTENT:
matrix_event_state_set_prev_content(matrix_event_state, g_value_get_boxed(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, property_id, pspec);
break;
}
}
static void
matrix_event_state_class_init(MatrixEventStateClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_state_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_state_real_to_json;
G_OBJECT_CLASS(klass)->get_property = matrix_event_state_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_state_set_property;
G_OBJECT_CLASS(klass)->finalize = matrix_event_state_finalize;
/**
* MatrixEventState:state-key:
*
* The state key of the event.
*/
matrix_event_state_properties[PROP_STATE_KEY] = g_param_spec_string(
"state-key", "state-key", "state-key",
NULL,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_STATE_KEY, matrix_event_state_properties[PROP_STATE_KEY]);
/**
* MatrixEventState:prev-content:
*
* The previous known content of the state
*/
matrix_event_state_properties[PROP_PREV_CONTENT] = g_param_spec_boxed(
"prev-content", "prev-content", "prev-content",
JSON_TYPE_NODE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass), PROP_PREV_CONTENT, matrix_event_state_properties[PROP_PREV_CONTENT]);
}
static void
matrix_event_state_init(MatrixEventState *matrix_event_state)
{
MatrixEventStatePrivate *priv;
priv = matrix_event_state_get_instance_private(matrix_event_state);
priv->_prev_content = NULL;
priv->_state_key = NULL;
}

View File

@@ -0,0 +1,53 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_STATE_BASE_H__
# define __MATRIX_GLIB_SDK_EVENT_STATE_BASE_H__
# include <glib-object.h>
# include <json-glib/json-glib.h>
# include "matrix-event-room-base.h"
# define MATRIX_EVENT_TYPE_STATE matrix_event_state_get_type()
#define MATRIX_EVENT_STATE(o) (G_TYPE_CHECK_INSTANCE_CAST((o), MATRIX_EVENT_TYPE_STATE, MatrixEventState))
#define MATRIX_EVENT_STATE_CLASS(c) (G_TYPE_CHECK_CLASS_CAST((c), MATRIX_EVENT_TYPE_STATE, MatrixEventStateClass))
#define MATRIX_EVENT_IS_STATE(o) (G_TYPE_CHECK_INSTANCE_TYPE((o), MATRIX_EVENT_TYPE_STATE))
#define MATRIX_EVENT_IS_STATE_CLASS(c) (G_TYPE_CHECK_CLASS_TYPE((c), MATRIX_EVENT_TYPE_STATE))
#define MATRIX_EVENT_STATE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS((o), MATRIX_EVENT_TYPE_STATE, MatrixEventStateClass))
typedef struct _MatrixEventStateClass MatrixEventStateClass;
typedef struct _MatrixEventState MatrixEventState;
G_DEFINE_AUTOPTR_CLEANUP_FUNC(MatrixEventState, g_object_unref);
struct _MatrixEventStateClass {
MatrixEventRoomClass parent_class;
};
struct _MatrixEventState {
MatrixEventRoom parent_instance;
};
GType matrix_event_state_get_type(void);
JsonNode *matrix_event_state_get_stripped_node(MatrixEventState *event);
MatrixEventState *matrix_event_state_construct(GType object_type);
const gchar *matrix_event_state_get_state_key(MatrixEventState *event);
void matrix_event_state_set_state_key(MatrixEventState *event, const gchar *state_key);
JsonNode *matrix_event_state_get_prev_content(MatrixEventState *event);
void matrix_event_state_set_prev_content(MatrixEventState *event, JsonNode *prev_content);
#endif /* __MATRIX_GLIB_SDK_EVENT_STATE_BASE_H__ */

View File

@@ -1,95 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
public abstract class Matrix.Event.State : Matrix.Event.Room {
protected string? _state_key;
public string? state_key {
get {
return _state_key;
}
set {
_state_key = value;
}
default = null;
}
public Json.Node? prev_content { get; set; default = null; }
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var root = json_data.get_object();
Json.Node? node;
if ((node = root.get_member("state_key")) != null) {
_state_key = node.get_string();
} else if (Config.DEBUG) {
warning("state_key is not present in a State event");
}
if ((node = root.get_member("prev_content")) != null) {
_prev_content = node;
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_node)
throws Matrix.Error
{
if (_state_key == null) {
throw new Matrix.Error.INCOMPLETE(
"Won't generate state events without state_key");
}
var root = json_node.get_object();
root.set_string_member("state_key", state_key);
if (_prev_content != null) {
root.set_member("prev_content", prev_content);
}
base.to_json(json_node);
}
/**
* Get a stripped state event.
*
* @return `null` if the event is not allowed to be stripped, or
* the full JSON node otherwise
*/
public Json.Node?
get_stripped_node()
{
if ((_event_type != "m.room.join_rules")
&& (_event_type != "m.room.canonical_alias")
&& (_event_type != "m.room.avatar")
&& (_event_type != "m.room.name")) {
warning("Trying to strip down event that is not allowed to be stripped.");
return null;
}
return json;
}
}

265
src/matrix-event-tag.c Normal file
View File

@@ -0,0 +1,265 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#include "matrix-event-tag.h"
/**
* SECTION:matrix-event-tag
* @short_description: Event handling class for `m.room.tag`
*
* This is the default event handler for `m.room.tag` events.
*/
typedef struct {
GHashTable *tags;
} MatrixEventTagPrivate;
enum {
PROP_0,
PROP_TAGS,
NUM_PROPS
};
static GParamSpec *matrix_event_tag_properties[NUM_PROPS];
/**
* MatrixEventTag:
*
* Object structure
*/
G_DEFINE_TYPE_WITH_PRIVATE(MatrixEventTag, matrix_event_tag, MATRIX_EVENT_TYPE_BASE);
static void
matrix_event_tag_real_from_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventTagPrivate *priv = matrix_event_tag_get_instance_private(MATRIX_EVENT_TAG(matrix_event_base));
JsonObject *root;
JsonNode *content_node;
JsonObject *content_root;
JsonNode *node;
GError *inner_error = NULL;
g_return_if_fail(json_data != NULL);
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
if ((node = json_object_get_member(content_root, "tags")) != NULL) {
JsonObjectIter iter;
JsonObject *tags_root = json_node_get_object(node);
const gchar *member_name;
JsonNode *member_node;
json_object_iter_init(&iter, tags_root);
while (json_object_iter_next(&iter, &member_name, &member_node)) {
if (priv->tags == NULL) {
priv->tags = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)json_node_unref);
}
g_hash_table_replace(priv->tags, g_strdup(member_name), json_node_ref(member_node));
}
json_node_free(node);
}
MATRIX_EVENT_BASE_CLASS(matrix_event_tag_parent_class)->from_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
static void
matrix_event_tag_real_to_json(MatrixEventBase *matrix_event_base, JsonNode *json_data, GError **error)
{
MatrixEventTagPrivate *priv;
GError *inner_error = NULL;
priv = matrix_event_tag_get_instance_private(MATRIX_EVENT_TAG(matrix_event_base));
if (priv->tags != NULL) {
JsonObject *tags_root = json_object_new();
GHashTableIter iter;
gpointer key;
gpointer value;
g_hash_table_iter_init(&iter, priv->tags);
while (g_hash_table_iter_next(&iter, &key, &value)) {
gchar *tag = (gchar *)key;
JsonNode *tag_contents = (JsonNode *)value;
json_object_set_member(tags_root, tag, tag_contents);
}
if (json_object_get_size(tags_root) > 0) {
JsonObject *root;
JsonObject *content_root;
JsonNode *content_node;
JsonNode *tags_node;
root = json_node_get_object(json_data);
content_node = json_object_get_member(root, "content");
content_root = json_node_get_object(content_node);
tags_node = json_node_new(JSON_NODE_OBJECT);
json_node_set_object(tags_node, tags_root);
json_object_set_member(content_root, "tags", tags_node);
}
}
MATRIX_EVENT_BASE_CLASS(matrix_event_tag_parent_class)->to_json(matrix_event_base, json_data, &inner_error);
if (inner_error != NULL) {
g_propagate_error(error, inner_error);
}
}
MatrixEventTag *
matrix_event_tag_construct(GType object_type)
{
return (MatrixEventTag *)matrix_event_base_construct(object_type);
}
/**
* matrix_event_tag_new:
*
* Create a new #MatrixEventTag object
*
* Returns: (transfer full): a new #MatrixEventTag object
*/
MatrixEventTag *
matrix_event_tag_new(void)
{
return matrix_event_tag_construct(MATRIX_EVENT_TYPE_TAG);
}
/**
* matrix_event_tag_get_tags:
* @event: a #MatrixEventTag
*
* Get the list of tags as a #GHashTable
*
* The returned value is owned by @event and should not be freed.
*
* Returns: (transfer none) (nullable): the list of tags
*/
GHashTable *
matrix_event_tag_get_tags(MatrixEventTag *event)
{
MatrixEventTagPrivate *priv = matrix_event_tag_get_instance_private(event);
g_return_val_if_fail(event != NULL, NULL);
return priv->tags;
}
/**
* matrix_event_tag_set_tags:
* @event: a #MatrixEventTag
* @tags: (transfer none) (nullable): a #GHashTable
*
* Set the tag list of @event.
*
* @tags, if not %NULL, must be a #GHashTable whose keys are strings, and values are
* #JsonNode objects.
*
* @event creates a reference on @tags, so it can be released by the caller.
*/
void
matrix_event_tag_set_tags(MatrixEventTag *event, GHashTable *tags)
{
MatrixEventTagPrivate *priv = matrix_event_tag_get_instance_private(event);
g_return_if_fail(event != NULL);
g_hash_table_unref(priv->tags);
priv->tags = g_hash_table_ref(tags);
}
static void
matrix_event_tag_finalize(GObject *gobject)
{
MatrixEventTagPrivate *priv = matrix_event_tag_get_instance_private(MATRIX_EVENT_TAG(gobject));
g_hash_table_unref(priv->tags);
G_OBJECT_CLASS(matrix_event_tag_parent_class)->finalize(gobject);
}
static void
matrix_event_tag_set_property(GObject *gobject, guint prop_id, const GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_TAGS:
matrix_event_tag_set_tags(MATRIX_EVENT_TAG(gobject), g_value_get_boxed(value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
}
}
static void
matrix_event_tag_get_property(GObject *gobject, guint prop_id, GValue *value, GParamSpec *pspec)
{
switch (prop_id) {
case PROP_TAGS:
g_value_set_boxed(value, matrix_event_tag_get_tags(MATRIX_EVENT_TAG(gobject)));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, pspec);
break;
}
}
static void
matrix_event_tag_class_init(MatrixEventTagClass *klass)
{
((MatrixEventBaseClass *)klass)->from_json = matrix_event_tag_real_from_json;
((MatrixEventBaseClass *)klass)->to_json = matrix_event_tag_real_to_json;
G_OBJECT_CLASS(klass)->finalize = matrix_event_tag_finalize;
G_OBJECT_CLASS(klass)->get_property = matrix_event_tag_get_property;
G_OBJECT_CLASS(klass)->set_property = matrix_event_tag_set_property;
/**
* MatrixEventTag:tags:
*
* The list of tags as a #GHashTable.
*/
matrix_event_tag_properties[PROP_TAGS] = g_param_spec_boxed(
"tags", "tags", "tags",
G_TYPE_HASH_TABLE,
G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE);
g_object_class_install_property(G_OBJECT_CLASS(klass),
PROP_TAGS,
matrix_event_tag_properties[PROP_TAGS]);
}
static void
matrix_event_tag_init(MatrixEventTag *matrix_event_tag)
{
MatrixEventTagPrivate *priv = matrix_event_tag_get_instance_private(matrix_event_tag);
priv->tags = NULL;
}

41
src/matrix-event-tag.h Normal file
View File

@@ -0,0 +1,41 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
#ifndef __MATRIX_GLIB_SDK_EVENT_TAG_H__
# define __MATRIX_GLIB_SDK_EVENT_TAG_H__
# include <glib-object.h>
# include "matrix-event-base.h"
G_BEGIN_DECLS
# define MATRIX_EVENT_TYPE_TAG matrix_event_tag_get_type()
G_DECLARE_DERIVABLE_TYPE(MatrixEventTag, matrix_event_tag, MATRIX_EVENT, TAG, MatrixEventBase);
struct _MatrixEventTagClass {
MatrixEventBaseClass parent_class;
};
MatrixEventTag* matrix_event_tag_new(void);
MatrixEventTag* matrix_event_tag_construct(GType object_type);
GHashTable *matrix_event_tag_get_tags(MatrixEventTag *event);
void matrix_event_tag_set_tags(MatrixEventTag *event, GHashTable *tags);
G_END_DECLS
#endif /* __MATRIX_GLIB_SDK_EVENT_TAG_H__ */

View File

@@ -1,69 +0,0 @@
/*
* This file is part of matrix-glib-sdk
*
* matrix-glib-sdk is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* matrix-glib-sdk 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with matrix-glib-sdk. If not, see
* <http://www.gnu.org/licenses/>.
*/
public class Matrix.Event.Tag : Matrix.Event.Base {
private HashTable<string, Json.Node>? _tags = null;
protected override void
from_json(Json.Node json_data)
throws Matrix.Error
{
var content_root = json_data.get_object()
.get_member("content").get_object();
Json.Node? node;
if ((node = content_root.get_member("tags")) != null) {
var tags_root = node.get_object();
tags_root.foreach_member((tobj, tag, tag_contents) => {
if (_tags == null) {
_tags = new HashTable<string, Json.Node>(
str_hash, str_equal);
}
_tags.replace(tag, tag_contents);
});
}
base.from_json(json_data);
}
protected override void
to_json(Json.Node json_data)
throws Matrix.Error
{
if (_tags != null) {
var tags_root = new Json.Object();
_tags.foreach((tag, tag_contents) => {
tags_root.set_member(tag, tag_contents);
});
if (tags_root.get_size() > 0) {
var content_root = json_data.get_object()
.get_member("content").get_object();
var tags_node = new Json.Node(Json.NodeType.OBJECT);
tags_node.set_object(tags_root);
content_root.set_member("tags", tags_node);
}
}
base.to_json(json_data);
}
}

Some files were not shown because too many files have changed in this diff Show More