[-]
[+]
|
Changed |
libguac-client-rdp.changes
|
|
[-]
[+]
|
Changed |
libguac-client-rdp.spec
^
|
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/ChangeLog
^
|
@@ -1,3 +1,27 @@
+2012-12-13 Michael Jumper <zhangmaike@users.sourceforge.net>
+
+ * Implement PATBLT fallback (fixes #238)
+
+2012-11-22 Michael Jumper <zhangmaike@users.sourceforge.net>
+
+ * Add disable-audio option (fixes #221)
+
+2012-11-02 Michael Jumper <zhangmaike@users.sourceforge.net>
+
+ * Added sound support (fixes #32)
+
+2012-10-22 Michael Jumper <zhangmaike@users.sourceforge.net>
+
+ * Use guac_client_info to choose optimal size if size not overridden
+
+2012-08-31 Laurent Meunier <laurent@deltalima.net>
+
+ * Use configured color depth
+
+2012-08-11 Michael Jumper <zhangmaike@users.sourceforge.net>
+
+ * Fix m4/ autoreconf error
+
2012-05-23 David Pham-Van <d.pham-van@ulteo.com>
* Add SetNull and SetDefault handlers (fixes #148)
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/Makefile.am
^
|
@@ -37,18 +37,39 @@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = -Werror -Wall -pedantic -Iinclude
+AM_CFLAGS = -Werror -Wall -Iinclude
lib_LTLIBRARIES = libguac-client-rdp.la
+freerdp_LTLIBRARIES = guac_rdpsnd.la
-libguac_client_rdp_la_SOURCES = src/client.c src/rdp_bitmap.c src/rdp_glyph.c src/rdp_pointer.c src/rdp_gdi.c src/guac_handlers.c src/rdp_cliprdr.c \
- src/rdp_keymap.c \
- src/rdp_keymap_base.c \
- src/rdp_keymap_en_us.c \
- src/default_pointer.c
+libguac_client_rdp_la_SOURCES = \
+ $(OGG_SOURCES) \
+ src/audio.c \
+ src/client.c \
+ src/default_pointer.c \
+ src/guac_handlers.c \
+ src/rdp_bitmap.c \
+ src/rdp_cliprdr.c \
+ src/rdp_gdi.c \
+ src/rdp_glyph.c \
+ src/rdp_keymap_base.c \
+ src/rdp_keymap.c \
+ src/rdp_keymap_en_us.c \
+ src/rdp_pointer.c \
+ src/wav_encoder.c
+
+guac_rdpsnd_la_SOURCES = \
+ guac_rdpsnd/messages.c \
+ guac_rdpsnd/service.c \
+ src/audio.c
noinst_HEADERS = \
+ $(OGG_HEADERS) \
+ guac_rdpsnd/messages.h \
+ guac_rdpsnd/service.h \
+ include/audio.h \
include/client.h \
+ include/config.h \
include/default_pointer.h \
include/guac_handlers.h \
include/rdp_bitmap.h \
@@ -56,9 +77,20 @@
include/rdp_gdi.h \
include/rdp_glyph.h \
include/rdp_keymap.h \
- include/rdp_pointer.h
+ include/rdp_pointer.h \
+ include/wav_encoder.h
+
+# Compile OGG support if available
+if ENABLE_OGG
+ libguac_client_rdp_la_SOURCES += src/ogg_encoder.c
+ noinst_HEADERS += include/ogg_encoder.h
+endif
+
libguac_client_rdp_la_LDFLAGS = -version-info 0:0:0
+guac_rdpsnd_la_LDFLAGS = -module -avoid-version -shared
+
+freerdpdir = ${libdir}/freerdp/
EXTRA_DIST = LICENSE
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/Makefile.in
^
|
@@ -71,8 +71,12 @@
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
+
+# Compile OGG support if available
+@ENABLE_OGG_TRUE@am__append_1 = src/ogg_encoder.c
+@ENABLE_OGG_TRUE@am__append_2 = include/ogg_encoder.h
subdir = .
-DIST_COMMON = README $(am__configure_deps) $(noinst_HEADERS) \
+DIST_COMMON = README $(am__configure_deps) $(am__noinst_HEADERS_DIST) \
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(top_srcdir)/configure AUTHORS ChangeLog config.guess \
config.sub depcomp install-sh ltmain.sh missing
@@ -109,13 +113,26 @@
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(libdir)"
-LTLIBRARIES = $(lib_LTLIBRARIES)
+am__installdirs = "$(DESTDIR)$(freerdpdir)" "$(DESTDIR)$(libdir)"
+LTLIBRARIES = $(freerdp_LTLIBRARIES) $(lib_LTLIBRARIES)
+guac_rdpsnd_la_LIBADD =
+am_guac_rdpsnd_la_OBJECTS = messages.lo service.lo audio.lo
+guac_rdpsnd_la_OBJECTS = $(am_guac_rdpsnd_la_OBJECTS)
+guac_rdpsnd_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
+ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
+ $(guac_rdpsnd_la_LDFLAGS) $(LDFLAGS) -o $@
libguac_client_rdp_la_LIBADD =
-am_libguac_client_rdp_la_OBJECTS = client.lo rdp_bitmap.lo \
- rdp_glyph.lo rdp_pointer.lo rdp_gdi.lo guac_handlers.lo \
- rdp_cliprdr.lo rdp_keymap.lo rdp_keymap_base.lo \
- rdp_keymap_en_us.lo default_pointer.lo
+am__libguac_client_rdp_la_SOURCES_DIST = src/audio.c src/client.c \
+ src/default_pointer.c src/guac_handlers.c src/rdp_bitmap.c \
+ src/rdp_cliprdr.c src/rdp_gdi.c src/rdp_glyph.c \
+ src/rdp_keymap_base.c src/rdp_keymap.c src/rdp_keymap_en_us.c \
+ src/rdp_pointer.c src/wav_encoder.c src/ogg_encoder.c
+@ENABLE_OGG_TRUE@am__objects_1 = ogg_encoder.lo
+am_libguac_client_rdp_la_OBJECTS = audio.lo client.lo \
+ default_pointer.lo guac_handlers.lo rdp_bitmap.lo \
+ rdp_cliprdr.lo rdp_gdi.lo rdp_glyph.lo rdp_keymap_base.lo \
+ rdp_keymap.lo rdp_keymap_en_us.lo rdp_pointer.lo \
+ wav_encoder.lo $(am__objects_1)
libguac_client_rdp_la_OBJECTS = $(am_libguac_client_rdp_la_OBJECTS)
libguac_client_rdp_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
@@ -133,8 +150,15 @@
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
$(LDFLAGS) -o $@
-SOURCES = $(libguac_client_rdp_la_SOURCES)
-DIST_SOURCES = $(libguac_client_rdp_la_SOURCES)
+SOURCES = $(guac_rdpsnd_la_SOURCES) $(libguac_client_rdp_la_SOURCES)
+DIST_SOURCES = $(guac_rdpsnd_la_SOURCES) \
+ $(am__libguac_client_rdp_la_SOURCES_DIST)
+am__noinst_HEADERS_DIST = guac_rdpsnd/messages.h guac_rdpsnd/service.h \
+ include/audio.h include/client.h include/config.h \
+ include/default_pointer.h include/guac_handlers.h \
+ include/rdp_bitmap.h include/rdp_cliprdr.h include/rdp_gdi.h \
+ include/rdp_glyph.h include/rdp_keymap.h include/rdp_pointer.h \
+ include/wav_encoder.h include/ogg_encoder.h
HEADERS = $(noinst_HEADERS)
ETAGS = etags
CTAGS = ctags
@@ -262,26 +286,30 @@
top_srcdir = @top_srcdir@
AUTOMAKE_OPTIONS = foreign
ACLOCAL_AMFLAGS = -I m4
-AM_CFLAGS = -Werror -Wall -pedantic -Iinclude
+AM_CFLAGS = -Werror -Wall -Iinclude
lib_LTLIBRARIES = libguac-client-rdp.la
-libguac_client_rdp_la_SOURCES = src/client.c src/rdp_bitmap.c src/rdp_glyph.c src/rdp_pointer.c src/rdp_gdi.c src/guac_handlers.c src/rdp_cliprdr.c \
- src/rdp_keymap.c \
- src/rdp_keymap_base.c \
- src/rdp_keymap_en_us.c \
- src/default_pointer.c
-
-noinst_HEADERS = \
- include/client.h \
- include/default_pointer.h \
- include/guac_handlers.h \
- include/rdp_bitmap.h \
- include/rdp_cliprdr.h \
- include/rdp_gdi.h \
- include/rdp_glyph.h \
- include/rdp_keymap.h \
- include/rdp_pointer.h
-
+freerdp_LTLIBRARIES = guac_rdpsnd.la
+libguac_client_rdp_la_SOURCES = $(OGG_SOURCES) src/audio.c \
+ src/client.c src/default_pointer.c src/guac_handlers.c \
+ src/rdp_bitmap.c src/rdp_cliprdr.c src/rdp_gdi.c \
+ src/rdp_glyph.c src/rdp_keymap_base.c src/rdp_keymap.c \
+ src/rdp_keymap_en_us.c src/rdp_pointer.c src/wav_encoder.c \
+ $(am__append_1)
+guac_rdpsnd_la_SOURCES = \
+ guac_rdpsnd/messages.c \
+ guac_rdpsnd/service.c \
+ src/audio.c
+
+noinst_HEADERS = $(OGG_HEADERS) guac_rdpsnd/messages.h \
+ guac_rdpsnd/service.h include/audio.h include/client.h \
+ include/config.h include/default_pointer.h \
+ include/guac_handlers.h include/rdp_bitmap.h \
+ include/rdp_cliprdr.h include/rdp_gdi.h include/rdp_glyph.h \
+ include/rdp_keymap.h include/rdp_pointer.h \
+ include/wav_encoder.h $(am__append_2)
libguac_client_rdp_la_LDFLAGS = -version-info 0:0:0
+guac_rdpsnd_la_LDFLAGS = -module -avoid-version -shared
+freerdpdir = ${libdir}/freerdp/
EXTRA_DIST = LICENSE
all: all-am
@@ -321,6 +349,37 @@
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
$(am__aclocal_m4_deps):
+install-freerdpLTLIBRARIES: $(freerdp_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(freerdpdir)" || $(MKDIR_P) "$(DESTDIR)$(freerdpdir)"
+ @list='$(freerdp_LTLIBRARIES)'; test -n "$(freerdpdir)" || list=; \
+ list2=; for p in $$list; do \
+ if test -f $$p; then \
+ list2="$$list2 $$p"; \
+ else :; fi; \
+ done; \
+ test -z "$$list2" || { \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(freerdpdir)'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(freerdpdir)"; \
+ }
+
+uninstall-freerdpLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(freerdp_LTLIBRARIES)'; test -n "$(freerdpdir)" || list=; \
+ for p in $$list; do \
+ $(am__strip_dir) \
+ echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(freerdpdir)/$$f'"; \
+ $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(freerdpdir)/$$f"; \
+ done
+
+clean-freerdpLTLIBRARIES:
+ -test -z "$(freerdp_LTLIBRARIES)" || rm -f $(freerdp_LTLIBRARIES)
+ @list='$(freerdp_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
@@ -352,6 +411,8 @@
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
+guac_rdpsnd.la: $(guac_rdpsnd_la_OBJECTS) $(guac_rdpsnd_la_DEPENDENCIES)
+ $(guac_rdpsnd_la_LINK) -rpath $(freerdpdir) $(guac_rdpsnd_la_OBJECTS) $(guac_rdpsnd_la_LIBADD) $(LIBS)
libguac-client-rdp.la: $(libguac_client_rdp_la_OBJECTS) $(libguac_client_rdp_la_DEPENDENCIES)
$(libguac_client_rdp_la_LINK) -rpath $(libdir) $(libguac_client_rdp_la_OBJECTS) $(libguac_client_rdp_la_LIBADD) $(LIBS)
@@ -361,9 +422,12 @@
distclean-compile:
-rm -f *.tab.c
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/audio.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/client.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/default_pointer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/guac_handlers.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/messages.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ogg_encoder.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdp_bitmap.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdp_cliprdr.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdp_gdi.Plo@am__quote@
@@ -372,6 +436,8 @@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdp_keymap_base.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdp_keymap_en_us.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rdp_pointer.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/service.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wav_encoder.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -394,6 +460,27 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+messages.lo: guac_rdpsnd/messages.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT messages.lo -MD -MP -MF $(DEPDIR)/messages.Tpo -c -o messages.lo `test -f 'guac_rdpsnd/messages.c' || echo '$(srcdir)/'`guac_rdpsnd/messages.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/messages.Tpo $(DEPDIR)/messages.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guac_rdpsnd/messages.c' object='messages.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o messages.lo `test -f 'guac_rdpsnd/messages.c' || echo '$(srcdir)/'`guac_rdpsnd/messages.c
+
+service.lo: guac_rdpsnd/service.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT service.lo -MD -MP -MF $(DEPDIR)/service.Tpo -c -o service.lo `test -f 'guac_rdpsnd/service.c' || echo '$(srcdir)/'`guac_rdpsnd/service.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/service.Tpo $(DEPDIR)/service.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='guac_rdpsnd/service.c' object='service.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o service.lo `test -f 'guac_rdpsnd/service.c' || echo '$(srcdir)/'`guac_rdpsnd/service.c
+
+audio.lo: src/audio.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT audio.lo -MD -MP -MF $(DEPDIR)/audio.Tpo -c -o audio.lo `test -f 'src/audio.c' || echo '$(srcdir)/'`src/audio.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/audio.Tpo $(DEPDIR)/audio.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/audio.c' object='audio.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o audio.lo `test -f 'src/audio.c' || echo '$(srcdir)/'`src/audio.c
+
client.lo: src/client.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT client.lo -MD -MP -MF $(DEPDIR)/client.Tpo -c -o client.lo `test -f 'src/client.c' || echo '$(srcdir)/'`src/client.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/client.Tpo $(DEPDIR)/client.Plo
@@ -401,6 +488,20 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o client.lo `test -f 'src/client.c' || echo '$(srcdir)/'`src/client.c
+default_pointer.lo: src/default_pointer.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT default_pointer.lo -MD -MP -MF $(DEPDIR)/default_pointer.Tpo -c -o default_pointer.lo `test -f 'src/default_pointer.c' || echo '$(srcdir)/'`src/default_pointer.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/default_pointer.Tpo $(DEPDIR)/default_pointer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/default_pointer.c' object='default_pointer.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o default_pointer.lo `test -f 'src/default_pointer.c' || echo '$(srcdir)/'`src/default_pointer.c
+
+guac_handlers.lo: src/guac_handlers.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT guac_handlers.lo -MD -MP -MF $(DEPDIR)/guac_handlers.Tpo -c -o guac_handlers.lo `test -f 'src/guac_handlers.c' || echo '$(srcdir)/'`src/guac_handlers.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/guac_handlers.Tpo $(DEPDIR)/guac_handlers.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/guac_handlers.c' object='guac_handlers.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o guac_handlers.lo `test -f 'src/guac_handlers.c' || echo '$(srcdir)/'`src/guac_handlers.c
+
rdp_bitmap.lo: src/rdp_bitmap.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_bitmap.lo -MD -MP -MF $(DEPDIR)/rdp_bitmap.Tpo -c -o rdp_bitmap.lo `test -f 'src/rdp_bitmap.c' || echo '$(srcdir)/'`src/rdp_bitmap.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_bitmap.Tpo $(DEPDIR)/rdp_bitmap.Plo
@@ -408,19 +509,12 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_bitmap.lo `test -f 'src/rdp_bitmap.c' || echo '$(srcdir)/'`src/rdp_bitmap.c
-rdp_glyph.lo: src/rdp_glyph.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_glyph.lo -MD -MP -MF $(DEPDIR)/rdp_glyph.Tpo -c -o rdp_glyph.lo `test -f 'src/rdp_glyph.c' || echo '$(srcdir)/'`src/rdp_glyph.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_glyph.Tpo $(DEPDIR)/rdp_glyph.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_glyph.c' object='rdp_glyph.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_glyph.lo `test -f 'src/rdp_glyph.c' || echo '$(srcdir)/'`src/rdp_glyph.c
-
-rdp_pointer.lo: src/rdp_pointer.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_pointer.lo -MD -MP -MF $(DEPDIR)/rdp_pointer.Tpo -c -o rdp_pointer.lo `test -f 'src/rdp_pointer.c' || echo '$(srcdir)/'`src/rdp_pointer.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_pointer.Tpo $(DEPDIR)/rdp_pointer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_pointer.c' object='rdp_pointer.lo' libtool=yes @AMDEPBACKSLASH@
+rdp_cliprdr.lo: src/rdp_cliprdr.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_cliprdr.lo -MD -MP -MF $(DEPDIR)/rdp_cliprdr.Tpo -c -o rdp_cliprdr.lo `test -f 'src/rdp_cliprdr.c' || echo '$(srcdir)/'`src/rdp_cliprdr.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_cliprdr.Tpo $(DEPDIR)/rdp_cliprdr.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_cliprdr.c' object='rdp_cliprdr.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_pointer.lo `test -f 'src/rdp_pointer.c' || echo '$(srcdir)/'`src/rdp_pointer.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_cliprdr.lo `test -f 'src/rdp_cliprdr.c' || echo '$(srcdir)/'`src/rdp_cliprdr.c
rdp_gdi.lo: src/rdp_gdi.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_gdi.lo -MD -MP -MF $(DEPDIR)/rdp_gdi.Tpo -c -o rdp_gdi.lo `test -f 'src/rdp_gdi.c' || echo '$(srcdir)/'`src/rdp_gdi.c
@@ -429,19 +523,19 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_gdi.lo `test -f 'src/rdp_gdi.c' || echo '$(srcdir)/'`src/rdp_gdi.c
-guac_handlers.lo: src/guac_handlers.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT guac_handlers.lo -MD -MP -MF $(DEPDIR)/guac_handlers.Tpo -c -o guac_handlers.lo `test -f 'src/guac_handlers.c' || echo '$(srcdir)/'`src/guac_handlers.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/guac_handlers.Tpo $(DEPDIR)/guac_handlers.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/guac_handlers.c' object='guac_handlers.lo' libtool=yes @AMDEPBACKSLASH@
+rdp_glyph.lo: src/rdp_glyph.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_glyph.lo -MD -MP -MF $(DEPDIR)/rdp_glyph.Tpo -c -o rdp_glyph.lo `test -f 'src/rdp_glyph.c' || echo '$(srcdir)/'`src/rdp_glyph.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_glyph.Tpo $(DEPDIR)/rdp_glyph.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_glyph.c' object='rdp_glyph.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o guac_handlers.lo `test -f 'src/guac_handlers.c' || echo '$(srcdir)/'`src/guac_handlers.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_glyph.lo `test -f 'src/rdp_glyph.c' || echo '$(srcdir)/'`src/rdp_glyph.c
-rdp_cliprdr.lo: src/rdp_cliprdr.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_cliprdr.lo -MD -MP -MF $(DEPDIR)/rdp_cliprdr.Tpo -c -o rdp_cliprdr.lo `test -f 'src/rdp_cliprdr.c' || echo '$(srcdir)/'`src/rdp_cliprdr.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_cliprdr.Tpo $(DEPDIR)/rdp_cliprdr.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_cliprdr.c' object='rdp_cliprdr.lo' libtool=yes @AMDEPBACKSLASH@
+rdp_keymap_base.lo: src/rdp_keymap_base.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_keymap_base.lo -MD -MP -MF $(DEPDIR)/rdp_keymap_base.Tpo -c -o rdp_keymap_base.lo `test -f 'src/rdp_keymap_base.c' || echo '$(srcdir)/'`src/rdp_keymap_base.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_keymap_base.Tpo $(DEPDIR)/rdp_keymap_base.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_keymap_base.c' object='rdp_keymap_base.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_cliprdr.lo `test -f 'src/rdp_cliprdr.c' || echo '$(srcdir)/'`src/rdp_cliprdr.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_keymap_base.lo `test -f 'src/rdp_keymap_base.c' || echo '$(srcdir)/'`src/rdp_keymap_base.c
rdp_keymap.lo: src/rdp_keymap.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_keymap.lo -MD -MP -MF $(DEPDIR)/rdp_keymap.Tpo -c -o rdp_keymap.lo `test -f 'src/rdp_keymap.c' || echo '$(srcdir)/'`src/rdp_keymap.c
@@ -450,13 +544,6 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_keymap.lo `test -f 'src/rdp_keymap.c' || echo '$(srcdir)/'`src/rdp_keymap.c
-rdp_keymap_base.lo: src/rdp_keymap_base.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_keymap_base.lo -MD -MP -MF $(DEPDIR)/rdp_keymap_base.Tpo -c -o rdp_keymap_base.lo `test -f 'src/rdp_keymap_base.c' || echo '$(srcdir)/'`src/rdp_keymap_base.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_keymap_base.Tpo $(DEPDIR)/rdp_keymap_base.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_keymap_base.c' object='rdp_keymap_base.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_keymap_base.lo `test -f 'src/rdp_keymap_base.c' || echo '$(srcdir)/'`src/rdp_keymap_base.c
-
rdp_keymap_en_us.lo: src/rdp_keymap_en_us.c
@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_keymap_en_us.lo -MD -MP -MF $(DEPDIR)/rdp_keymap_en_us.Tpo -c -o rdp_keymap_en_us.lo `test -f 'src/rdp_keymap_en_us.c' || echo '$(srcdir)/'`src/rdp_keymap_en_us.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_keymap_en_us.Tpo $(DEPDIR)/rdp_keymap_en_us.Plo
@@ -464,12 +551,26 @@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_keymap_en_us.lo `test -f 'src/rdp_keymap_en_us.c' || echo '$(srcdir)/'`src/rdp_keymap_en_us.c
-default_pointer.lo: src/default_pointer.c
-@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT default_pointer.lo -MD -MP -MF $(DEPDIR)/default_pointer.Tpo -c -o default_pointer.lo `test -f 'src/default_pointer.c' || echo '$(srcdir)/'`src/default_pointer.c
-@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/default_pointer.Tpo $(DEPDIR)/default_pointer.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/default_pointer.c' object='default_pointer.lo' libtool=yes @AMDEPBACKSLASH@
+rdp_pointer.lo: src/rdp_pointer.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT rdp_pointer.lo -MD -MP -MF $(DEPDIR)/rdp_pointer.Tpo -c -o rdp_pointer.lo `test -f 'src/rdp_pointer.c' || echo '$(srcdir)/'`src/rdp_pointer.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/rdp_pointer.Tpo $(DEPDIR)/rdp_pointer.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/rdp_pointer.c' object='rdp_pointer.lo' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o default_pointer.lo `test -f 'src/default_pointer.c' || echo '$(srcdir)/'`src/default_pointer.c
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o rdp_pointer.lo `test -f 'src/rdp_pointer.c' || echo '$(srcdir)/'`src/rdp_pointer.c
+
+wav_encoder.lo: src/wav_encoder.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT wav_encoder.lo -MD -MP -MF $(DEPDIR)/wav_encoder.Tpo -c -o wav_encoder.lo `test -f 'src/wav_encoder.c' || echo '$(srcdir)/'`src/wav_encoder.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/wav_encoder.Tpo $(DEPDIR)/wav_encoder.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/wav_encoder.c' object='wav_encoder.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o wav_encoder.lo `test -f 'src/wav_encoder.c' || echo '$(srcdir)/'`src/wav_encoder.c
+
+ogg_encoder.lo: src/ogg_encoder.c
+@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ogg_encoder.lo -MD -MP -MF $(DEPDIR)/ogg_encoder.Tpo -c -o ogg_encoder.lo `test -f 'src/ogg_encoder.c' || echo '$(srcdir)/'`src/ogg_encoder.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ogg_encoder.Tpo $(DEPDIR)/ogg_encoder.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='src/ogg_encoder.c' object='ogg_encoder.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ogg_encoder.lo `test -f 'src/ogg_encoder.c' || echo '$(srcdir)/'`src/ogg_encoder.c
mostlyclean-libtool:
-rm -f *.lo
@@ -624,7 +725,7 @@
*.zip*) \
unzip $(distdir).zip ;;\
esac
- chmod -R a-w $(distdir); chmod a+w $(distdir)
+ chmod -R a-w $(distdir); chmod u+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
@@ -683,7 +784,7 @@
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
- for dir in "$(DESTDIR)$(libdir)"; do \
+ for dir in "$(DESTDIR)$(freerdpdir)" "$(DESTDIR)$(libdir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
@@ -713,8 +814,8 @@
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
-clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
- mostlyclean-am
+clean-am: clean-freerdpLTLIBRARIES clean-generic clean-libLTLIBRARIES \
+ clean-libtool mostlyclean-am
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
@@ -735,7 +836,7 @@
info-am:
-install-data-am:
+install-data-am: install-freerdpLTLIBRARIES
install-dvi: install-dvi-am
@@ -783,25 +884,28 @@
ps-am:
-uninstall-am: uninstall-libLTLIBRARIES
+uninstall-am: uninstall-freerdpLTLIBRARIES uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
- clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
- dist-all dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ \
- dist-xz dist-zip distcheck distclean distclean-compile \
- distclean-generic distclean-libtool distclean-tags \
- distcleancheck distdir distuninstallcheck dvi dvi-am html \
- html-am info info-am install install-am install-data \
- install-data-am install-dvi install-dvi-am install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-libLTLIBRARIES install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags uninstall uninstall-am uninstall-libLTLIBRARIES
+ clean-freerdpLTLIBRARIES clean-generic clean-libLTLIBRARIES \
+ clean-libtool ctags dist dist-all dist-bzip2 dist-gzip \
+ dist-lzma dist-shar dist-tarZ dist-xz dist-zip distcheck \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distcleancheck distdir \
+ distuninstallcheck dvi dvi-am html html-am info info-am \
+ install install-am install-data install-data-am install-dvi \
+ install-dvi-am install-exec install-exec-am \
+ install-freerdpLTLIBRARIES install-html install-html-am \
+ install-info install-info-am install-libLTLIBRARIES \
+ install-man install-pdf install-pdf-am install-ps \
+ install-ps-am install-strip installcheck installcheck-am \
+ installdirs maintainer-clean maintainer-clean-generic \
+ mostlyclean mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
+ uninstall-am uninstall-freerdpLTLIBRARIES \
+ uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/configure
^
|
@@ -744,6 +744,8 @@
am__EXEEXT_TRUE
LTLIBOBJS
LIBOBJS
+ENABLE_OGG_FALSE
+ENABLE_OGG_TRUE
CPP
OTOOL64
OTOOL
@@ -2815,7 +2817,7 @@
# Define the identity of the package.
PACKAGE=libguac-client-rdp
- VERSION=0.6.1
+ VERSION=0.7.1
cat >>confdefs.h <<_ACEOF
@@ -4694,13 +4696,13 @@
else
lt_cv_nm_interface="BSD nm"
echo "int some_variable = 0;" > conftest.$ac_ext
- (eval echo "\"\$as_me:4697: $ac_compile\"" >&5)
+ (eval echo "\"\$as_me:4699: $ac_compile\"" >&5)
(eval "$ac_compile" 2>conftest.err)
cat conftest.err >&5
- (eval echo "\"\$as_me:4700: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+ (eval echo "\"\$as_me:4702: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
(eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
cat conftest.err >&5
- (eval echo "\"\$as_me:4703: output\"" >&5)
+ (eval echo "\"\$as_me:4705: output\"" >&5)
cat conftest.out >&5
if $GREP 'External.*some_variable' conftest.out > /dev/null; then
lt_cv_nm_interface="MS dumpbin"
@@ -5906,7 +5908,7 @@
;;
*-*-irix6*)
# Find out which ABI we are using.
- echo '#line 5909 "configure"' > conftest.$ac_ext
+ echo '#line 5911 "configure"' > conftest.$ac_ext
if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5
(eval $ac_compile) 2>&5
ac_status=$?
@@ -7435,11 +7437,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7438: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7440: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7442: \$? = $ac_status" >&5
+ echo "$as_me:7444: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7774,11 +7776,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7777: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7779: $lt_compile\"" >&5)
(eval "$lt_compile" 2>conftest.err)
ac_status=$?
cat conftest.err >&5
- echo "$as_me:7781: \$? = $ac_status" >&5
+ echo "$as_me:7783: \$? = $ac_status" >&5
if (exit $ac_status) && test -s "$ac_outfile"; then
# The compiler can only warn and ignore the option if not recognized
# So say no if there are warnings other than the usual output.
@@ -7879,11 +7881,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7882: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7884: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7886: \$? = $ac_status" >&5
+ echo "$as_me:7888: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -7934,11 +7936,11 @@
-e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
-e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
-e 's:$: $lt_compiler_flag:'`
- (eval echo "\"\$as_me:7937: $lt_compile\"" >&5)
+ (eval echo "\"\$as_me:7939: $lt_compile\"" >&5)
(eval "$lt_compile" 2>out/conftest.err)
ac_status=$?
cat out/conftest.err >&5
- echo "$as_me:7941: \$? = $ac_status" >&5
+ echo "$as_me:7943: \$? = $ac_status" >&5
if (exit $ac_status) && test -s out/conftest2.$ac_objext
then
# The compiler can only warn and ignore the option if not recognized
@@ -10318,7 +10320,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10321 "configure"
+#line 10323 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10414,7 +10416,7 @@
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 10417 "configure"
+#line 10419 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -10979,6 +10981,138 @@
$as_echo "$as_me: WARNING: \"libfreerdp-codec is required (part of FreeRDP)\"" >&2;}
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; }
+if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lpthread $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_mutex_init ();
+int
+main ()
+{
+return pthread_mutex_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_pthread_pthread_mutex_init=yes
+else
+ ac_cv_lib_pthread_pthread_mutex_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_mutex_init" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBPTHREAD 1
+_ACEOF
+
+ LIBS="-lpthread $LIBS"
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \"libpthread is required\"" >&5
+$as_echo "$as_me: WARNING: \"libpthread is required\"" >&2;}
+fi
+
+
+# Check for libvorbisenc
+
+have_vorbisenc=yes
+ac_fn_c_check_header_mongrel "$LINENO" "vorbis/vorbisenc.h" "ac_cv_header_vorbis_vorbisenc_h" "$ac_includes_default"
+if test "x$ac_cv_header_vorbis_vorbisenc_h" = x""yes; then :
+
+else
+ have_vorbisenc=no
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for vorbis_encode_init in -lvorbisenc" >&5
+$as_echo_n "checking for vorbis_encode_init in -lvorbisenc... " >&6; }
+if test "${ac_cv_lib_vorbisenc_vorbis_encode_init+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lvorbisenc $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char vorbis_encode_init ();
+int
+main ()
+{
+return vorbis_encode_init ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_vorbisenc_vorbis_encode_init=yes
+else
+ ac_cv_lib_vorbisenc_vorbis_encode_init=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_vorbisenc_vorbis_encode_init" >&5
+$as_echo "$ac_cv_lib_vorbisenc_vorbis_encode_init" >&6; }
+if test "x$ac_cv_lib_vorbisenc_vorbis_encode_init" = x""yes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_LIBVORBISENC 1
+_ACEOF
+
+ LIBS="-lvorbisenc $LIBS"
+
+else
+ have_vorbisenc=no
+fi
+
+ if test "x${have_vorbisenc}" = "xyes"; then
+ ENABLE_OGG_TRUE=
+ ENABLE_OGG_FALSE='#'
+else
+ ENABLE_OGG_TRUE='#'
+ ENABLE_OGG_FALSE=
+fi
+
+
+if test "x${have_vorbisenc}" = "xno"
+then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING:
+ --------------------------------------------
+ Unable to find libvorbisenc.
+ Sound will not be encoded with Ogg Vorbis.
+ --------------------------------------------" >&5
+$as_echo "$as_me: WARNING:
+ --------------------------------------------
+ Unable to find libvorbisenc.
+ Sound will not be encoded with Ogg Vorbis.
+ --------------------------------------------" >&2;}
+else
+ $as_echo "#define ENABLE_OGG 1" >>confdefs.h
+
+fi
# Checks for header files.
for ac_header in guacamole/client.h guacamole/guacio.h guacamole/protocol.h freerdp/locale/keyboard.h freerdp/kbd/layouts.h
@@ -11239,6 +11373,10 @@
as_fn_error $? "conditional \"am__fastdepCC\" was never defined.
Usually this means the macro was only invoked conditionally." "$LINENO" 5
fi
+if test -z "${ENABLE_OGG_TRUE}" && test -z "${ENABLE_OGG_FALSE}"; then
+ as_fn_error $? "conditional \"ENABLE_OGG\" was never defined.
+Usually this means the macro was only invoked conditionally." "$LINENO" 5
+fi
: ${CONFIG_STATUS=./config.status}
ac_write_fail=0
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/configure.in
^
|
@@ -35,7 +35,7 @@
# ***** END LICENSE BLOCK *****
AC_INIT(src/client.c)
-AM_INIT_AUTOMAKE([libguac-client-rdp], 0.6.1)
+AM_INIT_AUTOMAKE([libguac-client-rdp], 0.7.1)
AC_CONFIG_MACRO_DIR([m4])
# Checks for programs.
@@ -51,6 +51,25 @@
AC_CHECK_LIB([freerdp-channels], [freerdp_channels_new],, AC_MSG_ERROR("libfreerdp-channels is required (part of FreeRDP)"))
AC_CHECK_LIB([freerdp-utils], [xzalloc],, AC_MSG_ERROR("libfreerdp-utils is required (part of FreeRDP)"))
AC_CHECK_LIB([freerdp-codec], [freerdp_image_convert],, AC_MSG_ERROR("libfreerdp-codec is required (part of FreeRDP)"))
+AC_CHECK_LIB([pthread], [pthread_mutex_init],, AC_MSG_ERROR("libpthread is required"))
+
+# Check for libvorbisenc
+
+have_vorbisenc=yes
+AC_CHECK_HEADER(vorbis/vorbisenc.h,, [have_vorbisenc=no])
+AC_CHECK_LIB([vorbisenc], [vorbis_encode_init],, [have_vorbisenc=no])
+AM_CONDITIONAL([ENABLE_OGG], [test "x${have_vorbisenc}" = "xyes"])
+
+if test "x${have_vorbisenc}" = "xno"
+then
+ AC_MSG_WARN([
+ --------------------------------------------
+ Unable to find libvorbisenc.
+ Sound will not be encoded with Ogg Vorbis.
+ --------------------------------------------])
+else
+ AC_DEFINE([ENABLE_OGG])
+fi
# Checks for header files.
AC_CHECK_HEADERS([guacamole/client.h guacamole/guacio.h guacamole/protocol.h freerdp/locale/keyboard.h freerdp/kbd/layouts.h])
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/guac_rdpsnd
^
|
+(directory)
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/guac_rdpsnd/messages.c
^
|
@@ -0,0 +1,313 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <freerdp/constants.h>
+#include <freerdp/types.h>
+#include <freerdp/utils/memory.h>
+#include <freerdp/utils/stream.h>
+#include <freerdp/utils/svc_plugin.h>
+
+#include <guacamole/client.h>
+
+#include "audio.h"
+#include "service.h"
+#include "messages.h"
+#include "client.h"
+
+/* MESSAGE HANDLERS */
+
+void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header) {
+
+ int server_format_count;
+ int server_version;
+ int i;
+
+ STREAM* output_stream;
+ int output_body_size;
+ unsigned char* output_stream_end;
+
+ rdp_guac_client_data* guac_client_data =
+ (rdp_guac_client_data*) audio->client->data;
+
+ /* Format header */
+ stream_seek(input_stream, 14);
+ stream_read_uint16(input_stream, server_format_count);
+ stream_seek_uint8(input_stream);
+ stream_read_uint16(input_stream, server_version);
+ stream_seek_uint8(input_stream);
+
+ /* Initialize Client Audio Formats and Version PDU */
+ output_stream = stream_new(24);
+ stream_write_uint8(output_stream, SNDC_FORMATS);
+ stream_write_uint8(output_stream, 0);
+
+ /* Fill in body size later */
+ stream_seek_uint16(output_stream); /* offset = 0x02 */
+
+ /* Flags, volume, and pitch */
+ stream_write_uint32(output_stream, TSSNDCAPS_ALIVE);
+ stream_write_uint32(output_stream, 0);
+ stream_write_uint32(output_stream, 0);
+
+ /* Datagram port (UDP) */
+ stream_write_uint16(output_stream, 0);
+
+ /* Fill in format count later */
+ stream_seek_uint16(output_stream); /* offset = 0x12 */
+
+ /* Version and padding */
+ stream_write_uint8(output_stream, 0);
+ stream_write_uint16(output_stream, 6);
+ stream_write_uint8(output_stream, 0);
+
+ /* Check each server format, respond if supported */
+ for (i=0; i < server_format_count; i++) {
+
+ unsigned char* format_start;
+
+ int format_tag;
+ int channels;
+ int rate;
+ int bps;
+ int body_size;
+
+ /* Remember position in stream */
+ stream_get_mark(input_stream, format_start);
+
+ /* Read format */
+ stream_read_uint16(input_stream, format_tag);
+ stream_read_uint16(input_stream, channels);
+ stream_read_uint32(input_stream, rate);
+ stream_seek_uint32(input_stream);
+ stream_seek_uint16(input_stream);
+ stream_read_uint16(input_stream, bps);
+
+ /* Skip past extra data */
+ stream_read_uint16(input_stream, body_size);
+ stream_seek(input_stream, body_size);
+
+ /* If PCM, accept */
+ if (format_tag == WAVE_FORMAT_PCM) {
+
+ /* If can fit another format, accept it */
+ if (rdpsnd->format_count < GUAC_RDP_MAX_FORMATS) {
+
+ /* Add channel */
+ int current = rdpsnd->format_count++;
+ rdpsnd->formats[current].rate = rate;
+ rdpsnd->formats[current].channels = channels;
+ rdpsnd->formats[current].bps = bps;
+
+ /* Log format */
+ guac_client_log_info(audio->client,
+ "Accepted format: %i-bit PCM with %i channels at "
+ "%i Hz",
+ bps, channels, rate);
+
+ /* Queue format for sending as accepted */
+ stream_check_size(output_stream, 18 + body_size);
+ stream_write(output_stream, format_start, 18 + body_size);
+
+ /*
+ * BEWARE that using stream_check_size means that any "marks"
+ * set via stream_set_mark on output_stream are invalid.
+ */
+
+ }
+
+ /* Otherwise, log that we dropped one */
+ else
+ guac_client_log_info(audio->client,
+ "Dropped valid format: %i-bit PCM with %i channels at "
+ "%i Hz",
+ bps, channels, rate);
+
+ }
+
+ }
+
+ /* Calculate size of PDU */
+ output_body_size = stream_get_length(output_stream) - 4;
+ stream_get_mark(output_stream, output_stream_end);
+
+ /* Set body size */
+ stream_set_pos(output_stream, 0x02);
+ stream_write_uint16(output_stream, output_body_size);
+
+ /* Set format count */
+ stream_set_pos(output_stream, 0x12);
+ stream_write_uint16(output_stream, rdpsnd->format_count);
+
+ /* Reposition cursor at end (necessary for message send) */
+ stream_set_mark(output_stream, output_stream_end);
+
+ /* Send accepted formats */
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+ svc_plugin_send((rdpSvcPlugin*)rdpsnd, output_stream);
+
+ /* If version greater than 6, must send Quality Mode PDU */
+ if (server_version >= 6) {
+
+ /* Always send High Quality for now */
+ output_stream = stream_new(8);
+ stream_write_uint8(output_stream, SNDC_QUALITYMODE);
+ stream_write_uint8(output_stream, 0);
+ stream_write_uint16(output_stream, 4);
+ stream_write_uint16(output_stream, HIGH_QUALITY);
+ stream_write_uint16(output_stream, 0);
+
+ svc_plugin_send((rdpSvcPlugin*)rdpsnd, output_stream);
+ }
+
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
+}
+
+/* server is getting a feel of the round trip time */
+void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header) {
+
+ int data_size;
+ STREAM* output_stream;
+
+ rdp_guac_client_data* guac_client_data =
+ (rdp_guac_client_data*) audio->client->data;
+
+ /* Read timestamp and data size */
+ stream_read_uint16(input_stream, rdpsnd->server_timestamp);
+ stream_read_uint16(input_stream, data_size);
+
+ /* Send training response */
+ output_stream = stream_new(8);
+ stream_write_uint8(output_stream, SNDC_TRAINING);
+ stream_write_uint8(output_stream, 0);
+ stream_write_uint16(output_stream, 4);
+ stream_write_uint16(output_stream, rdpsnd->server_timestamp);
+ stream_write_uint16(output_stream, data_size);
+
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+ svc_plugin_send((rdpSvcPlugin*) rdpsnd, output_stream);
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
+}
+
+void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header) {
+
+ unsigned char buffer[4];
+ int format;
+
+ /* Read wave information */
+ stream_read_uint16(input_stream, rdpsnd->server_timestamp);
+ stream_read_uint16(input_stream, format);
+ stream_read_uint8(input_stream, rdpsnd->waveinfo_block_number);
+ stream_seek(input_stream, 3);
+ stream_read(input_stream, buffer, 4);
+
+ /*
+ * Size of incoming wave data is equal to the body size field of this
+ * header, less the size of a WaveInfo PDU (not including the header),
+ * thus body_size - 12.
+ */
+ rdpsnd->incoming_wave_size = header->body_size - 12;
+
+ /* Read wave in next iteration */
+ rdpsnd->next_pdu_is_wave = true;
+
+ /* Init stream with requested format */
+ audio_stream_begin(audio,
+ rdpsnd->formats[format].rate,
+ rdpsnd->formats[format].channels,
+ rdpsnd->formats[format].bps);
+
+ /* Write initial 4 bytes of data */
+ audio_stream_write_pcm(audio, buffer, 4);
+
+}
+
+void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header) {
+
+ rdpSvcPlugin* plugin = (rdpSvcPlugin*)rdpsnd;
+
+ rdp_guac_client_data* guac_client_data =
+ (rdp_guac_client_data*) audio->client->data;
+
+ /* Wave Confirmation PDU */
+ STREAM* output_stream = stream_new(8);
+
+ /* Get wave data */
+ unsigned char* buffer = stream_get_head(input_stream) + 4;
+
+ /* Write rest of audio packet */
+ audio_stream_write_pcm(audio, buffer, rdpsnd->incoming_wave_size);
+ audio_stream_end(audio);
+
+ /* Write Wave Confirmation PDU */
+ stream_write_uint8(output_stream, SNDC_WAVECONFIRM);
+ stream_write_uint8(output_stream, 0);
+ stream_write_uint16(output_stream, 4);
+ stream_write_uint16(output_stream, rdpsnd->server_timestamp);
+ stream_write_uint8(output_stream, rdpsnd->waveinfo_block_number);
+ stream_write_uint8(output_stream, 0);
+
+ /* Send Wave Confirmation PDU */
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+ svc_plugin_send(plugin, output_stream);
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
+ /* We no longer expect to receive wave data */
+ rdpsnd->next_pdu_is_wave = false;
+
+}
+
+void guac_rdpsnd_close_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header) {
+
+ /* STUB: Do nothing for now */
+
+}
+
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/guac_rdpsnd/messages.h
^
|
@@ -0,0 +1,162 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __GUAC_RDPSND_MESSAGES_H
+#define __GUAC_RDPSND_MESSAGES_H
+
+/*
+ * PDU Message Types
+ */
+
+/**
+ * Close PDU
+ */
+#define SNDC_CLOSE 1
+
+/**
+ * WaveInfo PDU. This PDU is sent just before wave data is sent.
+ */
+#define SNDC_WAVE 2
+
+/**
+ * Wave Confirm PDU. This PDU is sent in response to the WaveInfo PDU,
+ * confirming it has been received and played.
+ */
+#define SNDC_WAVECONFIRM 5
+
+/**
+ * Training PDU. This PDU is sent by the server occasionally and must be
+ * responded to with another training PDU, similar to Guac's sync message.
+ */
+#define SNDC_TRAINING 6
+
+/**
+ * Server Audio Formats and Version PDU. This PDU is sent by the server to
+ * advertise to the client which audio formats are supported.
+ */
+#define SNDC_FORMATS 7
+
+/**
+ * Quality Mode PDU. This PDU must be sent by the client to select an audio
+ * quality mode if the server is at least version 6.
+ */
+#define SNDC_QUALITYMODE 12
+
+/*
+ * Quality Modes
+ */
+
+/**
+ * Dynamic Quality. The server will choose the audio quality based on its
+ * perception of latency.
+ */
+#define DYNAMIC_QUALITY 0x0000
+
+/**
+ * Medium Quality. The server prioritizes bandwidth over quality.
+ */
+#define MEDIUM_QUALITY 0x0001
+
+/**
+ * High Quality. The server prioritizes quality over bandwidth.
+ */
+#define HIGH_QUALITY 0x0002
+
+/*
+ * Capabilities
+ */
+#define TSSNDCAPS_ALIVE 1
+
+/*
+ * Sound Formats
+ */
+#define WAVE_FORMAT_PCM 1
+
+/**
+ * The header common to all RDPSND PDUs.
+ */
+typedef struct guac_rdpsnd_pdu_header {
+
+ /**
+ * The type of message represented by this PDU (SNDC_WAVE, etc.)
+ */
+ int message_type;
+
+ /**
+ * The size of the remainder of the message.
+ */
+ int body_size;
+
+} guac_rdpsnd_pdu_header;
+
+/**
+ * Handler for the SNDC_FORMATS (Server Audio Formats and Version) PDU.
+ */
+void guac_rdpsnd_formats_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header);
+
+/**
+ * Handler for the SNDC_TRAINING (Training) PDU.
+ */
+void guac_rdpsnd_training_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header);
+
+/**
+ * Handler for the SNDC_WAVE (WaveInfo) PDU.
+ */
+void guac_rdpsnd_wave_info_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header);
+
+/**
+ * Handler for the SNDWAV (Wave) PDU which follows any WaveInfo PDU.
+ */
+void guac_rdpsnd_wave_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header);
+
+/**
+ * Handler for the SNDC_CLOSE (Close) PDU.
+ */
+void guac_rdpsnd_close_handler(guac_rdpsndPlugin* rdpsnd,
+ audio_stream* audio, STREAM* input_stream,
+ guac_rdpsnd_pdu_header* header);
+
+#endif
+
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/guac_rdpsnd/service.c
^
|
@@ -0,0 +1,140 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <freerdp/constants.h>
+#include <freerdp/types.h>
+#include <freerdp/utils/memory.h>
+#include <freerdp/utils/stream.h>
+#include <freerdp/utils/svc_plugin.h>
+
+#include <guacamole/client.h>
+
+#include "audio.h"
+#include "service.h"
+#include "messages.h"
+
+
+/* Define service, associate with "rdpsnd" channel */
+
+DEFINE_SVC_PLUGIN(guac_rdpsnd, "rdpsnd",
+ CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP)
+
+
+/*
+ * Service Handlers
+ */
+
+void guac_rdpsnd_process_connect(rdpSvcPlugin* plugin) {
+
+ /* Get audio stream from plugin */
+ audio_stream* audio = (audio_stream*)
+ plugin->channel_entry_points.pExtendedData;
+
+ /* Update every 10 ms */
+ plugin->interval_ms = 10;
+
+ /* Log that sound has been loaded */
+ guac_client_log_info(audio->client, "guac_rdpsnd connected.");
+
+}
+
+void guac_rdpsnd_process_terminate(rdpSvcPlugin* plugin) {
+ xfree(plugin);
+}
+
+void guac_rdpsnd_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event) {
+ freerdp_event_free(event);
+}
+
+void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin,
+ STREAM* input_stream) {
+
+ guac_rdpsndPlugin* rdpsnd = (guac_rdpsndPlugin*) plugin;
+ guac_rdpsnd_pdu_header header;
+
+ /* Get audio stream from plugin */
+ audio_stream* audio = (audio_stream*)
+ plugin->channel_entry_points.pExtendedData;
+
+ /* Read RDPSND PDU header */
+ stream_read_uint8(input_stream, header.message_type);
+ stream_seek_uint8(input_stream);
+ stream_read_uint16(input_stream, header.body_size);
+
+ /*
+ * If next PDU is SNDWAVE (due to receiving WaveInfo PDU previously),
+ * ignore the header and parse as a Wave PDU.
+ */
+ if (rdpsnd->next_pdu_is_wave) {
+ guac_rdpsnd_wave_handler(rdpsnd, audio, input_stream, &header);
+ return;
+ }
+
+ /* Dispatch message to standard handlers */
+ switch (header.message_type) {
+
+ /* Server Audio Formats and Version PDU */
+ case SNDC_FORMATS:
+ guac_rdpsnd_formats_handler(rdpsnd, audio,
+ input_stream, &header);
+ break;
+
+ /* Training PDU */
+ case SNDC_TRAINING:
+ guac_rdpsnd_training_handler(rdpsnd, audio,
+ input_stream, &header);
+ break;
+
+ /* WaveInfo PDU */
+ case SNDC_WAVE:
+ guac_rdpsnd_wave_info_handler(rdpsnd, audio,
+ input_stream, &header);
+ break;
+
+ /* Close PDU */
+ case SNDC_CLOSE:
+ guac_rdpsnd_close_handler(rdpsnd, audio,
+ input_stream, &header);
+ break;
+
+ }
+
+}
+
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/guac_rdpsnd/service.h
^
|
@@ -0,0 +1,146 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __GUAC_RDPSND_SERVICE_H
+#define __GUAC_RDPSND_SERVICE_H
+
+/**
+ * The maximum number of PCM formats to accept during the initial RDPSND
+ * handshake with the RDP server.
+ */
+#define GUAC_RDP_MAX_FORMATS 16
+
+
+/**
+ * Abstract representation of a PCM format, including the sample rate, number
+ * of channels, and bits per sample.
+ */
+typedef struct guac_pcm_format {
+
+ /**
+ * The sample rate of this PCM format.
+ */
+ int rate;
+
+ /**
+ * The number off channels used by this PCM format. This will typically
+ * be 1 or 2.
+ */
+ int channels;
+
+ /**
+ * The number of bits per sample within this PCM format. This should be
+ * either 8 or 16.
+ */
+ int bps;
+
+} guac_pcm_format;
+
+
+/**
+ * Structure representing the current state of the Guacamole RDPSND plugin for
+ * FreeRDP.
+ */
+typedef struct guac_rdpsndPlugin {
+
+ /**
+ * The FreeRDP parts of this plugin. This absolutely MUST be first.
+ * FreeRDP depends on accessing this structure as if it were an instance
+ * of rdpSvcPlugin.
+ */
+ rdpSvcPlugin plugin;
+
+ /**
+ * The block number of the last SNDC_WAVE (WaveInfo) PDU received.
+ */
+ int waveinfo_block_number;
+
+ /**
+ * Whether the next PDU coming is a SNDWAVE (Wave) PDU. Wave PDUs do not
+ * have headers, and are indicated by the receipt of a WaveInfo PDU.
+ */
+ int next_pdu_is_wave;
+
+ /**
+ * The size, in bytes, of the wave data in the coming Wave PDU, if any.
+ */
+ int incoming_wave_size;
+
+ /**
+ * The last received server timestamp.
+ */
+ int server_timestamp;
+
+ /**
+ * All formats agreed upon by server and client during the initial format
+ * exchange. All of these formats will be PCM, which is the only format
+ * guaranteed to be supported (based on the official RDP documentation).
+ */
+ guac_pcm_format formats[GUAC_RDP_MAX_FORMATS];
+
+ /**
+ * The total number of formats.
+ */
+ int format_count;
+
+} guac_rdpsndPlugin;
+
+
+/**
+ * Handler called when this plugin is loaded by FreeRDP.
+ */
+void guac_rdpsnd_process_connect(rdpSvcPlugin* plugin);
+
+/**
+ * Handler called when this plugin receives data along its designated channel.
+ */
+void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin,
+ STREAM* input_stream);
+
+/**
+ * Handler called when this plugin is being unloaded.
+ */
+void guac_rdpsnd_process_terminate(rdpSvcPlugin* plugin);
+
+/**
+ * Handler called when this plugin receives an event. For the sake of RDPSND,
+ * all events will be ignored and simply free'd.
+ */
+void guac_rdpsnd_process_event(rdpSvcPlugin* plugin, RDP_EVENT* event);
+
+#endif
+
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/include/audio.h
^
|
@@ -0,0 +1,212 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __GUAC_TEST_AUDIO_H
+#define __GUAC_TEST_AUDIO_H
+
+#include <guacamole/client.h>
+#include <guacamole/stream.h>
+
+typedef struct audio_stream audio_stream;
+
+/**
+ * Handler which is called when the audio stream is opened.
+ */
+typedef void audio_encoder_begin_handler(audio_stream* audio);
+
+/**
+ * Handler which is called when the audio stream is closed.
+ */
+typedef void audio_encoder_end_handler(audio_stream* audio);
+
+/**
+ * Handler which is called when the audio stream is flushed.
+ */
+typedef void audio_encoder_write_handler(audio_stream* audio,
+ unsigned char* pcm_data, int length);
+
+/**
+ * Arbitrary audio codec encoder.
+ */
+typedef struct audio_encoder {
+
+ /**
+ * The mimetype of the audio data encoded by this audio
+ * encoder.
+ */
+ const char* mimetype;
+
+ /**
+ * Handler which will be called when the audio stream is opened.
+ */
+ audio_encoder_begin_handler* begin_handler;
+
+ /**
+ * Handler which will be called when the audio stream is flushed.
+ */
+ audio_encoder_write_handler* write_handler;
+
+ /**
+ * Handler which will be called when the audio stream is closed.
+ */
+ audio_encoder_end_handler* end_handler;
+
+} audio_encoder;
+
+/**
+ * Basic audio stream. PCM data is added to the stream. When the stream is
+ * flushed, a write handler receives PCM data packets and, presumably, streams
+ * them to the guac_stream provided.
+ */
+struct audio_stream {
+
+ /**
+ * PCM data buffer, 16-bit samples, 2-channel, 44100 Hz.
+ */
+ unsigned char* pcm_data;
+
+ /**
+ * Number of bytes in buffer.
+ */
+ int used;
+
+ /**
+ * Maximum number of bytes in buffer.
+ */
+ int length;
+
+ /**
+ * Encoded audio data buffer, as written by the encoder.
+ */
+ unsigned char* encoded_data;
+
+ /**
+ * Number of bytes in the encoded data buffer.
+ */
+ int encoded_data_used;
+
+ /**
+ * Maximum number of bytes in the encoded data buffer.
+ */
+ int encoded_data_length;
+
+ /**
+ * Arbitrary codec encoder. When the PCM buffer is flushed, PCM data will
+ * be sent to this encoder.
+ */
+ audio_encoder* encoder;
+
+ /**
+ * The client associated with this audio stream.
+ */
+ guac_client* client;
+
+ /**
+ * The actual stream associated with this audio stream.
+ */
+ guac_stream* stream;
+
+ /**
+ * The number of samples per second of PCM data sent to this stream.
+ */
+ int rate;
+
+ /**
+ * The number of audio channels per sample of PCM data. Legal values are
+ * 1 or 2.
+ */
+ int channels;
+
+ /**
+ * The number of bits per sample per channel for PCM data. Legal values are
+ * 8 or 16.
+ */
+ int bps;
+
+ /**
+ * The number of PCM bytes written since the audio chunk began.
+ */
+ int pcm_bytes_written;
+
+ /**
+ * Encoder-specific state data.
+ */
+ void* data;
+
+};
+
+/**
+ * Allocates a new audio stream.
+ */
+audio_stream* audio_stream_alloc(guac_client* client,
+ audio_encoder* encoder);
+
+/**
+ * Frees the given audio stream.
+ */
+void audio_stream_free(audio_stream* stream);
+
+/**
+ * Begins a new audio stream.
+ */
+void audio_stream_begin(audio_stream* stream, int rate, int channels, int bps);
+
+/**
+ * Ends the current audio stream.
+ */
+void audio_stream_end(audio_stream* stream);
+
+/**
+ * Writes PCM data to the given audio stream.
+ */
+void audio_stream_write_pcm(audio_stream* stream,
+ unsigned char* data, int length);
+
+/**
+ * Flushes the given audio stream.
+ */
+void audio_stream_flush(audio_stream* stream);
+
+/**
+ * Appends arbitrarily-encoded data to the encoded_data buffer
+ * within the given audio stream.
+ */
+void audio_stream_write_encoded(audio_stream* audio,
+ unsigned char* data, int length);
+
+#endif
+
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/include/client.h
^
|
@@ -38,11 +38,14 @@
#ifndef _GUAC_RDP_CLIENT_H
#define _GUAC_RDP_CLIENT_H
+#include <cairo/cairo.h>
+
#include <freerdp/freerdp.h>
#include <freerdp/codec/color.h>
#include <guacamole/client.h>
+#include "audio.h"
#include "rdp_keymap.h"
/**
@@ -51,6 +54,21 @@
#define RDP_DEFAULT_PORT 3389
/**
+ * Default screen width, in pixels.
+ */
+#define RDP_DEFAULT_WIDTH 1024
+
+/**
+ * Default screen height, in pixels.
+ */
+#define RDP_DEFAULT_HEIGHT 768
+
+/**
+ * Default color depth, in bits.
+ */
+#define RDP_DEFAULT_DEPTH 16
+
+/**
* Client data that will remain accessible through the guac_client.
* This should generally include data commonly used by Guacamole handlers.
*/
@@ -121,6 +139,28 @@
*/
char* clipboard;
+ /**
+ * Whether audio is enabled.
+ */
+ int audio_enabled;
+
+ /**
+ * Audio output, if any.
+ */
+ audio_stream* audio;
+
+ /**
+ * Lock which is locked and unlocked for each update.
+ */
+ pthread_mutex_t update_lock;
+
+ /**
+ * Lock which is locked and unlocked for each RDP message.
+ */
+ pthread_mutex_t rdp_lock;
+
+ pthread_mutexattr_t attributes;
+
} rdp_guac_client_data;
/**
|
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/include/config.h
^
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/include/ogg_encoder.h
^
|
@@ -0,0 +1,67 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __GUAC_OGG_ENCODER_H
+#define __GUAC_OGG_ENCODER_H
+
+#include "audio.h"
+
+#include <vorbis/vorbisenc.h>
+
+typedef struct ogg_encoder_state {
+
+ /**
+ * Ogg state
+ */
+ ogg_stream_state ogg_state;
+ ogg_page ogg_page;
+ ogg_packet ogg_packet;
+
+ /**
+ * Vorbis state
+ */
+ vorbis_info info;
+ vorbis_comment comment;
+ vorbis_dsp_state vorbis_state;
+ vorbis_block vorbis_block;
+
+} ogg_encoder_state;
+
+extern audio_encoder* ogg_encoder;
+
+#endif
+
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/include/wav_encoder.h
^
|
@@ -0,0 +1,144 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __GUAC_WAV_ENCODER_H
+#define __GUAC_WAV_ENCODER_H
+
+#include "audio.h"
+
+typedef struct wav_encoder_riff_header {
+
+ /**
+ * The RIFF chunk header, normally the string "RIFF".
+ */
+ unsigned char chunk_id[4];
+
+ /**
+ * Size of the entire file, not including chunk_id or chunk_size.
+ */
+ unsigned char chunk_size[4];
+
+ /**
+ * The format of this file, normally the string "WAVE".
+ */
+ unsigned char chunk_format[4];
+
+} wav_encoder_riff_header;
+
+typedef struct wav_encoder_fmt_header {
+
+ /**
+ * ID of this subchunk. For the fmt subchunk, this should be "fmt ".
+ */
+ unsigned char subchunk_id[4];
+
+ /**
+ * The size of the rest of this subchunk. For PCM, this will be 16.
+ */
+ unsigned char subchunk_size[4];
+
+ /**
+ * Format of this subchunk. For PCM, this will be 1.
+ */
+ unsigned char subchunk_format[2];
+
+ /**
+ * The number of channels in the PCM data.
+ */
+ unsigned char subchunk_channels[2];
+
+ /**
+ * The sample rate of the PCM data.
+ */
+ unsigned char subchunk_sample_rate[4];
+
+ /**
+ * The sample rate of the PCM data in bytes per second.
+ */
+ unsigned char subchunk_byte_rate[4];
+
+ /**
+ * The number of bytes per sample.
+ */
+ unsigned char subchunk_block_align[2];
+
+ /**
+ * The number of bits per sample.
+ */
+ unsigned char subchunk_bps[2];
+
+} wav_encoder_fmt_header;
+
+typedef struct wav_encoder_state {
+
+ /**
+ * Arbitrary PCM data available for writing when the overall WAV is
+ * flushed.
+ */
+ unsigned char* data_buffer;
+
+ /**
+ * The number of bytes currently present in the data buffer.
+ */
+ int used;
+
+ /**
+ * The total number of bytes that can be written into the data buffer
+ * without requiring resizing.
+ */
+ int length;
+
+} wav_encoder_state;
+
+typedef struct wav_encoder_data_header {
+
+ /**
+ * ID of this subchunk. For the data subchunk, this should be "data".
+ */
+ unsigned char subchunk_id[4];
+
+ /**
+ * The number of bytes in the PCM data.
+ */
+ unsigned char subchunk_size[4];
+
+} wav_encoder_data_header;
+
+extern audio_encoder* wav_encoder;
+
+#endif
+
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/src/audio.c
^
|
@@ -0,0 +1,179 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <guacamole/protocol.h>
+#include <guacamole/client.h>
+#include <guacamole/stream.h>
+
+#include "audio.h"
+#include "client.h"
+
+audio_stream* audio_stream_alloc(guac_client* client, audio_encoder* encoder) {
+
+ /* Allocate stream */
+ audio_stream* audio = (audio_stream*) malloc(sizeof(audio_stream));
+ audio->client = client;
+
+ /* Reset buffer stats */
+ audio->used = 0;
+ audio->length = 0x40000;
+
+ audio->encoded_data_used = 0;
+ audio->encoded_data_length = 0x40000;
+
+ /* Allocate buffers */
+ audio->pcm_data = malloc(audio->length);
+ audio->encoded_data = malloc(audio->encoded_data_length);
+
+ /* Assign encoder */
+ audio->encoder = encoder;
+ audio->stream = guac_client_alloc_stream(client);
+
+ return audio;
+}
+
+void audio_stream_begin(audio_stream* audio, int rate, int channels, int bps) {
+
+ /* Load PCM properties */
+ audio->rate = rate;
+ audio->channels = channels;
+ audio->bps = bps;
+
+ /* Reset write counter */
+ audio->pcm_bytes_written = 0;
+
+ /* Call handler */
+ audio->encoder->begin_handler(audio);
+
+}
+
+void audio_stream_end(audio_stream* audio) {
+
+ double duration;
+
+ rdp_guac_client_data* data = (rdp_guac_client_data*) audio->client->data;
+
+ /* Flush stream and finish encoding */
+ audio_stream_flush(audio);
+ audio->encoder->end_handler(audio);
+
+ /* Calculate duration of PCM data */
+ duration = ((double) (audio->pcm_bytes_written * 1000 * 8))
+ / audio->rate / audio->channels / audio->bps;
+
+ pthread_mutex_lock(&(data->update_lock));
+
+ /* Send audio */
+ guac_protocol_send_audio(audio->stream->socket,
+ 0, audio->encoder->mimetype,
+ duration, audio->encoded_data, audio->encoded_data_used);
+
+ pthread_mutex_unlock(&(data->update_lock));
+
+ /* Clear data */
+ audio->encoded_data_used = 0;
+
+}
+
+void audio_stream_free(audio_stream* audio) {
+ free(audio->pcm_data);
+ free(audio);
+}
+
+void audio_stream_write_pcm(audio_stream* audio,
+ unsigned char* data, int length) {
+
+ /* Update counter */
+ audio->pcm_bytes_written += length;
+
+ /* Resize audio buffer if necessary */
+ if (length > audio->length) {
+
+ /* Resize to double provided length */
+ audio->length = length*2;
+ audio->pcm_data = realloc(audio->pcm_data, audio->length);
+
+ }
+
+ /* Flush if necessary */
+ if (audio->used + length > audio->length)
+ audio_stream_flush(audio);
+
+ /* Append to buffer */
+ memcpy(&(audio->pcm_data[audio->used]), data, length);
+ audio->used += length;
+
+}
+
+void audio_stream_flush(audio_stream* audio) {
+
+ /* If data in buffer */
+ if (audio->used != 0) {
+
+ /* Write data */
+ audio->encoder->write_handler(audio,
+ audio->pcm_data, audio->used);
+
+ /* Reset buffer */
+ audio->used = 0;
+
+ }
+
+}
+
+void audio_stream_write_encoded(audio_stream* audio,
+ unsigned char* data, int length) {
+
+ /* Resize audio buffer if necessary */
+ if (audio->encoded_data_used + length > audio->encoded_data_length) {
+
+ /* Increase to double concatenated size to accomodate */
+ audio->encoded_data_length = (audio->encoded_data_length + length)*2;
+ audio->encoded_data = realloc(audio->encoded_data,
+ audio->encoded_data_length);
+
+ }
+
+ /* Append to buffer */
+ memcpy(&(audio->encoded_data[audio->encoded_data_used]), data, length);
+ audio->encoded_data_used += length;
+
+}
+
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/client.c
^
|
@@ -22,6 +22,7 @@
* Contributor(s):
* Matt Hortman
* David PHAM-VAN <d.pham-van@ulteo.com> Ulteo SAS - http://www.ulteo.com
+ * Laurent Meunier <laurent@deltalima.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@@ -37,8 +38,11 @@
*
* ***** END LICENSE BLOCK ***** */
+#define _XOPEN_SOURCE 500
+
#include <stdlib.h>
#include <string.h>
+#include <pthread.h>
#include <sys/select.h>
#include <errno.h>
@@ -60,6 +64,13 @@
#include <guacamole/client.h>
#include <guacamole/error.h>
+#include "audio.h"
+#include "wav_encoder.h"
+
+#ifdef ENABLE_OGG
+#include "ogg_encoder.h"
+#endif
+
#include "client.h"
#include "guac_handlers.h"
#include "rdp_keymap.h"
@@ -80,6 +91,7 @@
"height",
"initial-program",
"color-depth",
+ "disable-audio",
NULL
};
@@ -92,7 +104,8 @@
IDX_WIDTH,
IDX_HEIGHT,
IDX_INITIAL_PROGRAM,
- IDX_COLOR_DEPTH
+ IDX_COLOR_DEPTH,
+ IDX_DISABLE_AUDIO
};
int __guac_receive_channel_data(freerdp* rdp_inst, int channelId, uint8* data, int size, int flags, int total_size) {
@@ -109,9 +122,59 @@
rdpPointer* pointer;
rdpPrimaryUpdate* primary;
CLRCONV* clrconv;
+ int i;
+
+ rdp_guac_client_data* guac_client_data =
+ (rdp_guac_client_data*) client->data;
/* Load clipboard plugin */
- freerdp_channels_load_plugin(channels, instance->settings, "cliprdr", NULL);
+ if (freerdp_channels_load_plugin(channels, instance->settings,
+ "cliprdr", NULL))
+ guac_client_log_error(client, "Failed to load cliprdr plugin.");
+
+ /* If audio enabled, choose an encoder */
+ if (guac_client_data->audio_enabled) {
+
+ /* Choose an encoding */
+ for (i=0; client->info.audio_mimetypes[i] != NULL; i++) {
+
+ const char* mimetype = client->info.audio_mimetypes[i];
+
+#ifdef ENABLE_OGG
+ /* If Ogg is supported, done. */
+ if (strcmp(mimetype, ogg_encoder->mimetype) == 0) {
+ guac_client_log_info(client, "Loading Ogg Vorbis encoder.");
+ guac_client_data->audio = audio_stream_alloc(client,
+ ogg_encoder);
+ break;
+ }
+#endif
+
+ /* If wav is supported, done. */
+ if (strcmp(mimetype, wav_encoder->mimetype) == 0) {
+ guac_client_log_info(client, "Loading wav encoder.");
+ guac_client_data->audio = audio_stream_alloc(client,
+ wav_encoder);
+ break;
+ }
+
+ }
+
+ /* If an encoding is available, load the sound plugin */
+ if (guac_client_data->audio != NULL) {
+
+ /* Load sound plugin */
+ if (freerdp_channels_load_plugin(channels, instance->settings,
+ "guac_rdpsnd", guac_client_data->audio))
+ guac_client_log_error(client,
+ "Failed to load guac_rdpsnd plugin.");
+
+ }
+ else
+ guac_client_log_info(client,
+ "No available audio encoding. Sound disabled.");
+
+ } /* end if audio enabled */
/* Init color conversion structure */
clrconv = xnew(CLRCONV);
@@ -321,19 +384,31 @@
settings->encryption_method = ENCRYPTION_METHOD_40BIT | ENCRYPTION_METHOD_128BIT | ENCRYPTION_METHOD_FIPS;
settings->encryption_level = ENCRYPTION_LEVEL_CLIENT_COMPATIBLE;
- /* session width */
- settings->width = 1024;
+ /* Use optimal width unless overridden */
+ settings->width = client->info.optimal_width;
if (argv[IDX_WIDTH][0] != '\0')
settings->width = atoi(argv[IDX_WIDTH]);
- if (settings->width == 0)
- settings->width = 1024;
- /* session height */
- settings->height = 768;
+ /* Use default width if given width is invalid. */
+ if (settings->width <= 0) {
+ settings->width = RDP_DEFAULT_WIDTH;
+ guac_client_log_error(client,
+ "Invalid width: \"%s\". Using default of %i.",
+ argv[IDX_WIDTH], settings->width);
+ }
+
+ /* Use optimal height unless overridden */
+ settings->height = client->info.optimal_height;
if (argv[IDX_HEIGHT][0] != '\0')
settings->height = atoi(argv[IDX_HEIGHT]);
- if (settings->height == 0)
- settings->height = 768;
+
+ /* Use default height if given height is invalid. */
+ if (settings->height <= 0) {
+ settings->height = RDP_DEFAULT_HEIGHT;
+ guac_client_log_error(client,
+ "Invalid height: \"%s\". Using default of %i.",
+ argv[IDX_WIDTH], settings->height);
+ }
/* Set hostname */
settings->hostname = strdup(hostname);
@@ -358,6 +433,23 @@
if (argv[IDX_INITIAL_PROGRAM][0] != '\0')
settings->shell = strdup(argv[IDX_INITIAL_PROGRAM]);
+ /* Session color depth */
+ settings->color_depth = RDP_DEFAULT_DEPTH;
+ if (argv[IDX_COLOR_DEPTH][0] != '\0')
+ settings->color_depth = atoi(argv[IDX_COLOR_DEPTH]);
+
+ /* Use default depth if given depth is invalid. */
+ if (settings->color_depth == 0) {
+ settings->color_depth = RDP_DEFAULT_DEPTH;
+ guac_client_log_error(client,
+ "Invalid color-depth: \"%s\". Using default of %i.",
+ argv[IDX_WIDTH], settings->color_depth);
+ }
+
+ /* Audio enable/disable */
+ guac_client_data->audio_enabled =
+ (strcmp(argv[IDX_DISABLE_AUDIO], "true") != 0);
+
/* Order support */
bitmap_cache = settings->bitmap_cache;
settings->os_major_type = OSMAJORTYPE_UNSPECIFIED;
@@ -392,6 +484,20 @@
guac_client_data->mouse_button_mask = 0;
guac_client_data->current_surface = GUAC_DEFAULT_LAYER;
guac_client_data->clipboard = NULL;
+ guac_client_data->audio = NULL;
+
+ /* Recursive attribute for locks */
+ pthread_mutexattr_init(&(guac_client_data->attributes));
+ pthread_mutexattr_settype(&(guac_client_data->attributes),
+ PTHREAD_MUTEX_RECURSIVE);
+
+ /* Init update lock */
+ pthread_mutex_init(&(guac_client_data->update_lock),
+ &(guac_client_data->attributes));
+
+ /* Init RDP lock */
+ pthread_mutex_init(&(guac_client_data->rdp_lock),
+ &(guac_client_data->attributes));
/* Clear keysym state mapping and keymap */
memset(guac_client_data->keysym_state, 0,
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/guac_handlers.c
^
|
@@ -39,6 +39,7 @@
*
* ***** END LICENSE BLOCK ***** */
+#include <pthread.h>
#include <stdlib.h>
#include <string.h>
@@ -167,6 +168,8 @@
}
}
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+
/* Check the libfreerdp fds */
if (!freerdp_check_fds(rdp_inst)) {
guac_error = GUAC_STATUS_BAD_STATE;
@@ -200,6 +203,15 @@
return 1;
}
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
+ /* Flush any audio */
+ if (guac_client_data->audio != NULL) {
+ pthread_mutex_lock(&(guac_client_data->update_lock));
+ guac_socket_flush(guac_client_data->audio->stream->socket);
+ pthread_mutex_unlock(&(guac_client_data->update_lock));
+ }
+
/* Success */
return 0;
@@ -210,6 +222,8 @@
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
freerdp* rdp_inst = guac_client_data->rdp_inst;
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+
/* If button mask unchanged, just send move event */
if (mask == guac_client_data->mouse_button_mask)
rdp_inst->input->MouseEvent(rdp_inst->input, PTR_FLAGS_MOVE, x, y);
@@ -275,6 +289,8 @@
guac_client_data->mouse_button_mask = mask;
}
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
return 0;
}
@@ -294,6 +310,8 @@
/* If defined, send event */
if (keysym_desc->scancode != 0) {
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+
/* If defined, send any prerequesite keys that must be set */
if (keysym_desc->set_keysyms != NULL)
__guac_rdp_update_keysyms(client, keysym_desc->set_keysyms, 0, 1);
@@ -317,6 +335,8 @@
if (keysym_desc->clear_keysyms != NULL)
__guac_rdp_update_keysyms(client, keysym_desc->clear_keysyms, 1, 1);
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
return 0;
}
@@ -344,10 +364,15 @@
guac_client_log_info(client, "Translated keysym 0x%x to U+%04X",
keysym, codepoint);
+ pthread_mutex_lock(&(guac_client_data->rdp_lock));
+
/* Send Unicode event */
rdp_inst->input->UnicodeKeyboardEvent(
rdp_inst->input,
0, codepoint);
+
+ pthread_mutex_unlock(&(guac_client_data->rdp_lock));
+
}
else
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/src/ogg_encoder.c
^
|
@@ -0,0 +1,211 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#include <stdlib.h>
+
+#include <guacamole/client.h>
+#include <guacamole/protocol.h>
+
+#include <vorbis/vorbisenc.h>
+
+#include "audio.h"
+#include "ogg_encoder.h"
+
+void ogg_encoder_begin_handler(audio_stream* audio) {
+
+ /* Allocate stream state */
+ ogg_encoder_state* state = (ogg_encoder_state*)
+ malloc(sizeof(ogg_encoder_state));
+
+ /* Init state */
+ vorbis_info_init(&(state->info));
+ vorbis_encode_init_vbr(&(state->info), audio->channels, audio->rate, 0.4);
+
+ vorbis_analysis_init(&(state->vorbis_state), &(state->info));
+ vorbis_block_init(&(state->vorbis_state), &(state->vorbis_block));
+
+ vorbis_comment_init(&(state->comment));
+ vorbis_comment_add_tag(&(state->comment), "ENCODER", "libguac-client-rdp");
+
+ ogg_stream_init(&(state->ogg_state), rand());
+
+ /* Write headers */
+ {
+ ogg_packet header;
+ ogg_packet header_comm;
+ ogg_packet header_code;
+
+ vorbis_analysis_headerout(
+ &(state->vorbis_state),
+ &(state->comment),
+ &header, &header_comm, &header_code);
+
+ ogg_stream_packetin(&(state->ogg_state), &header);
+ ogg_stream_packetin(&(state->ogg_state), &header_comm);
+ ogg_stream_packetin(&(state->ogg_state), &header_code);
+
+ /* For each packet */
+ while (ogg_stream_flush(&(state->ogg_state), &(state->ogg_page)) != 0) {
+
+ /* Write packet header */
+ audio_stream_write_encoded(audio,
+ state->ogg_page.header,
+ state->ogg_page.header_len);
+
+ /* Write packet body */
+ audio_stream_write_encoded(audio,
+ state->ogg_page.body,
+ state->ogg_page.body_len);
+ }
+
+ }
+
+ audio->data = state;
+
+}
+
+void ogg_encoder_write_blocks(audio_stream* audio) {
+
+ /* Get state */
+ ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
+
+ while (vorbis_analysis_blockout(&(state->vorbis_state),
+ &(state->vorbis_block)) == 1) {
+
+ /* Analyze */
+ vorbis_analysis(&(state->vorbis_block), NULL);
+ vorbis_bitrate_addblock(&(state->vorbis_block));
+
+ /* Flush Ogg pages */
+ while (vorbis_bitrate_flushpacket(&(state->vorbis_state),
+ &(state->ogg_packet))) {
+
+ /* Weld packet into bitstream */
+ ogg_stream_packetin(&(state->ogg_state), &(state->ogg_packet));
+
+ /* Write out pages */
+ while (ogg_stream_pageout(&(state->ogg_state),
+ &(state->ogg_page)) != 0) {
+
+ /* Write packet header */
+ audio_stream_write_encoded(audio,
+ state->ogg_page.header,
+ state->ogg_page.header_len);
+
+ /* Write packet body */
+ audio_stream_write_encoded(audio,
+ state->ogg_page.body,
+ state->ogg_page.body_len);
+
+ if (ogg_page_eos(&(state->ogg_page)))
+ break;
+
+ }
+
+ }
+
+ }
+
+}
+
+void ogg_encoder_end_handler(audio_stream* audio) {
+
+ /* Get state */
+ ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
+
+ /* Write end-of-stream */
+ vorbis_analysis_wrote(&(state->vorbis_state), 0);
+ ogg_encoder_write_blocks(audio);
+
+ /* Clean up encoder */
+ ogg_stream_clear(&(state->ogg_state));
+ vorbis_block_clear(&(state->vorbis_block));
+ vorbis_dsp_clear(&(state->vorbis_state));
+ vorbis_comment_clear(&(state->comment));
+ vorbis_info_clear(&(state->info));
+
+ /* Free stream state */
+ free(audio->data);
+
+}
+
+void ogg_encoder_write_handler(audio_stream* audio,
+ unsigned char* pcm_data, int length) {
+
+ /* Get state */
+ ogg_encoder_state* state = (ogg_encoder_state*) audio->data;
+
+ /* Calculate samples */
+ int samples = length / audio->channels * 8 / audio->bps;
+ int i;
+
+ /* Get buffer */
+ float** buffer = vorbis_analysis_buffer(&(state->vorbis_state), samples);
+
+ signed char* readbuffer = (signed char*) pcm_data;
+
+ for (i=0; i<samples; i++) {
+
+ /* FIXME: For now, assume 2 channels, 16-bit */
+ int left = ((readbuffer[i*4+1]<<8)|(0x00ff&(int)readbuffer[i*4]));
+ int right = ((readbuffer[i*4+3]<<8)|(0x00ff&(int)readbuffer[i*4+2]));
+
+ /* Store sample in buffer */
+ buffer[0][i] = left / 32768.f;
+ buffer[1][i] = right / 32768.f;
+
+ }
+
+ /* Submit data */
+ vorbis_analysis_wrote(&(state->vorbis_state), samples);
+
+ /* Write data */
+ ogg_encoder_write_blocks(audio);
+
+}
+
+/* Encoder handlers */
+audio_encoder _ogg_encoder = {
+ .mimetype = "audio/ogg",
+ .begin_handler = ogg_encoder_begin_handler,
+ .write_handler = ogg_encoder_write_handler,
+ .end_handler = ogg_encoder_end_handler
+};
+
+/* Actual encoder */
+audio_encoder* ogg_encoder = &_ogg_encoder;
+
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/rdp_bitmap.c
^
|
@@ -38,6 +38,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include <pthread.h>
#include <cairo/cairo.h>
@@ -64,6 +65,9 @@
/* Cache image data if present */
if (bitmap->data != NULL) {
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
/* Create surface from image data */
cairo_surface_t* surface = cairo_image_surface_create_for_data(
bitmap->data, CAIRO_FORMAT_RGB24,
@@ -76,6 +80,7 @@
/* Free surface */
cairo_surface_destroy(surface);
+ pthread_mutex_unlock(&(data->update_lock));
}
/* Store buffer reference in bitmap */
@@ -120,6 +125,9 @@
int width = bitmap->right - bitmap->left + 1;
int height = bitmap->bottom - bitmap->top + 1;
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
/* If not cached, cache if necessary */
if (((guac_rdp_bitmap*) bitmap)->layer == NULL
&& ((guac_rdp_bitmap*) bitmap)->used >= 1)
@@ -154,6 +162,7 @@
/* Increment usage counter */
((guac_rdp_bitmap*) bitmap)->used++;
+ pthread_mutex_unlock(&(data->update_lock));
}
void guac_rdp_bitmap_free(rdpContext* context, rdpBitmap* bitmap) {
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/rdp_cliprdr.c
^
|
@@ -42,6 +42,7 @@
#include <freerdp/plugins/cliprdr.h>
#include <guacamole/client.h>
+#include <guacamole/protocol.h>
#include "client.h"
#include "rdp_cliprdr.h"
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/rdp_gdi.c
^
|
@@ -36,6 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
+#include <pthread.h>
#include <freerdp/freerdp.h>
#include <guacamole/client.h>
@@ -106,6 +107,9 @@
guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
switch (dstblt->bRop) {
/* Blackness */
@@ -129,19 +133,122 @@
}
-
+ pthread_mutex_unlock(&(data->update_lock));
}
void guac_rdp_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) {
+
+ /*
+ * Note that this is not a full implementation of PATBLT. This is a
+ * fallback implementation which only renders a solid block of background
+ * color using the specified ROP3 operation, ignoring whatever brush
+ * was actually specified.
+ *
+ * As libguac-client-rdp explicitly tells the server not to send PATBLT,
+ * well-behaved RDP servers will not use this operation at all, while
+ * others will at least have a fallback.
+ */
+
+ /* Get client and current layer */
guac_client* client = ((rdp_freerdp_context*) context)->client;
- guac_client_log_info(client, "guac_rdp_gdi_patblt()");
+ const guac_layer* current_layer =
+ ((rdp_guac_client_data*) client->data)->current_surface;
+
+ /* Layer for actual transfer */
+ guac_layer* buffer;
+
+ /*
+ * Warn that rendering is a fallback, as the server should not be sending
+ * this order.
+ */
+ guac_client_log_info(client, "Using fallback PATBLT (server is ignoring "
+ "negotiated client capabilities)");
+
+ /* Render rectangle based on ROP */
+ switch (patblt->bRop) {
+
+ /* If blackness, send black rectangle */
+ case 0x00:
+ guac_protocol_send_rect(client->socket, current_layer,
+ patblt->nLeftRect, patblt->nTopRect,
+ patblt->nWidth, patblt->nHeight);
+
+ guac_protocol_send_cfill(client->socket,
+ GUAC_COMP_OVER, current_layer,
+ 0x00, 0x00, 0x00, 0xFF);
+ break;
+
+ /* If NOP, do nothing */
+ case 0xAA:
+ break;
+
+ /* If operation is just a copy, send foreground only */
+ case 0xCC:
+ case 0xF0:
+ guac_protocol_send_rect(client->socket, current_layer,
+ patblt->nLeftRect, patblt->nTopRect,
+ patblt->nWidth, patblt->nHeight);
+
+ guac_protocol_send_cfill(client->socket,
+ GUAC_COMP_OVER, current_layer,
+ (patblt->foreColor >> 16) & 0xFF,
+ (patblt->foreColor >> 8 ) & 0xFF,
+ (patblt->foreColor ) & 0xFF,
+ 0xFF);
+ break;
+
+ /* If whiteness, send white rectangle */
+ case 0xFF:
+ guac_protocol_send_rect(client->socket, current_layer,
+ patblt->nLeftRect, patblt->nTopRect,
+ patblt->nWidth, patblt->nHeight);
+
+ guac_protocol_send_cfill(client->socket,
+ GUAC_COMP_OVER, current_layer,
+ 0xFF, 0xFF, 0xFF, 0xFF);
+ break;
+
+ /* Otherwise, invert entire rect */
+ default:
+
+ /* Allocate buffer for transfer */
+ buffer = guac_client_alloc_buffer(client);
+
+ /* Send rectangle stroke */
+ guac_protocol_send_rect(client->socket, buffer,
+ 0, 0, patblt->nWidth, patblt->nHeight);
+
+ /* Fill rectangle with fore color only */
+ guac_protocol_send_cfill(client->socket, GUAC_COMP_OVER, buffer,
+ 0xFF, 0xFF, 0xFF, 0xFF);
+
+ /* Transfer */
+ guac_protocol_send_transfer(client->socket,
+
+ /* ... from buffer */
+ buffer, 0, 0, patblt->nWidth, patblt->nHeight,
+
+ /* ... inverting */
+ GUAC_TRANSFER_BINARY_XOR,
+
+ /* ... to current layer */
+ current_layer, patblt->nLeftRect, patblt->nTopRect);
+
+ /* Done with buffer */
+ guac_client_free_buffer(client, buffer);
+
+ }
+
}
void guac_rdp_gdi_scrblt(rdpContext* context, SCRBLT_ORDER* scrblt) {
guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
+
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
/* Copy screen rect to current surface */
guac_protocol_send_copy(client->socket,
@@ -150,6 +257,8 @@
GUAC_COMP_OVER, current_layer,
scrblt->nLeftRect, scrblt->nTopRect);
+ pthread_mutex_unlock(&(data->update_lock));
+
}
void guac_rdp_gdi_memblt(rdpContext* context, MEMBLT_ORDER* memblt) {
@@ -159,6 +268,9 @@
guac_socket* socket = client->socket;
guac_rdp_bitmap* bitmap = (guac_rdp_bitmap*) memblt->bitmap;
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
switch (memblt->bRop) {
/* If blackness, send black rectangle */
@@ -250,6 +362,8 @@
}
+ pthread_mutex_unlock(&(data->update_lock));
+
}
void guac_rdp_gdi_opaquerect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) {
@@ -261,6 +375,9 @@
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
guac_protocol_send_rect(client->socket, current_layer,
opaque_rect->nLeftRect, opaque_rect->nTopRect,
opaque_rect->nWidth, opaque_rect->nHeight);
@@ -272,6 +389,8 @@
(color ) & 0xFF,
255);
+ pthread_mutex_unlock(&(data->update_lock));
+
}
void guac_rdp_gdi_palette_update(rdpContext* context, PALETTE_UPDATE* palette) {
@@ -287,6 +406,9 @@
guac_client* client = ((rdp_freerdp_context*) context)->client;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
/* Reset clip */
guac_protocol_send_reset(client->socket, current_layer);
@@ -300,6 +422,8 @@
guac_protocol_send_clip(client->socket, current_layer);
}
+ pthread_mutex_unlock(&(data->update_lock));
+
}
void guac_rdp_gdi_end_paint(rdpContext* context) {
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/rdp_glyph.c
^
|
@@ -36,6 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
+#include <pthread.h>
#include <freerdp/freerdp.h>
#include <guacamole/client.h>
@@ -203,6 +204,8 @@
rdp_guac_client_data* guac_client_data = (rdp_guac_client_data*) client->data;
const guac_layer* current_layer = ((rdp_guac_client_data*) client->data)->current_surface;
+ pthread_mutex_lock(&(guac_client_data->update_lock));
+
/* Use glyph surface to provide image data for glyph rectangle */
cairo_surface_t* glyph_surface = guac_client_data->glyph_surface;
int stride = cairo_image_surface_get_stride(glyph_surface);
@@ -235,5 +238,6 @@
/* Destroy cairo instance */
cairo_destroy(guac_client_data->glyph_cairo);
+ pthread_mutex_unlock(&(guac_client_data->update_lock));
}
|
[-]
[+]
|
Changed |
libguac-client-rdp-0.7.1.tar.bz2/src/rdp_pointer.c
^
|
@@ -36,7 +36,7 @@
*
* ***** END LICENSE BLOCK ***** */
-
+#include <pthread.h>
#include <freerdp/freerdp.h>
#include <guacamole/client.h>
@@ -59,6 +59,9 @@
cairo_surface_t* surface;
+ rdp_guac_client_data* client_data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(client_data->update_lock));
+
/* Convert to alpha cursor if mask data present */
if (pointer->andMaskData && pointer->xorMaskData)
freerdp_alpha_cursor_convert(data,
@@ -81,6 +84,7 @@
/* Remember buffer */
((guac_rdp_pointer*) pointer)->layer = buffer;
+ pthread_mutex_unlock(&(client_data->update_lock));
}
void guac_rdp_pointer_set(rdpContext* context, rdpPointer* pointer) {
@@ -88,11 +92,15 @@
guac_client* client = ((rdp_freerdp_context*) context)->client;
guac_socket* socket = client->socket;
+ rdp_guac_client_data* data = (rdp_guac_client_data*) client->data;
+ pthread_mutex_lock(&(data->update_lock));
+
/* Set cursor */
guac_protocol_send_cursor(socket, pointer->xPos, pointer->yPos,
((guac_rdp_pointer*) pointer)->layer,
0, 0, pointer->width, pointer->height);
+ pthread_mutex_unlock(&(data->update_lock));
}
void guac_rdp_pointer_free(rdpContext* context, rdpPointer* pointer) {
|
[-]
[+]
|
Added |
libguac-client-rdp-0.7.1.tar.bz2/src/wav_encoder.c
^
|
@@ -0,0 +1,201 @@
+
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is libguac-client-rdp.
+ *
+ * The Initial Developer of the Original Code is
+ * Michael Jumper.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#define WAV_BUFFER_SIZE 0x4000
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <guacamole/client.h>
+#include <guacamole/protocol.h>
+
+#include "audio.h"
+#include "wav_encoder.h"
+
+void wav_encoder_begin_handler(audio_stream* audio) {
+
+ /* Allocate stream state */
+ wav_encoder_state* state = (wav_encoder_state*)
+ malloc(sizeof(wav_encoder_state));
+
+ /* Initialize buffer */
+ state->length = WAV_BUFFER_SIZE;
+ state->used = 0;
+ state->data_buffer = (unsigned char*) malloc(state->length);
+
+ audio->data = state;
+
+}
+
+void _wav_encoder_write_le(unsigned char* buffer, int value, int length) {
+
+ int offset;
+
+ /* Write all bytes in the given value in little-endian byte order */
+ for (offset=0; offset<length; offset++) {
+
+ /* Store byte */
+ *buffer = value & 0xFF;
+
+ /* Move to next byte */
+ value >>= 8;
+ buffer++;
+
+ }
+
+}
+
+void wav_encoder_end_handler(audio_stream* audio) {
+
+ /*
+ * Static header init
+ */
+
+ wav_encoder_riff_header riff_header = {
+ .chunk_id = "RIFF",
+ .chunk_format = "WAVE"
+ };
+
+ wav_encoder_fmt_header fmt_header = {
+ .subchunk_id = "fmt ",
+ .subchunk_size = {0x10, 0x00, 0x00, 0x00}, /* 16 */
+ .subchunk_format = {0x01, 0x00} /* 1 = PCM */
+ };
+
+ wav_encoder_data_header data_header = {
+ .subchunk_id = "data"
+ };
+
+ /* Get state */
+ wav_encoder_state* state = (wav_encoder_state*) audio->data;
+
+ /*
+ * RIFF HEADER
+ */
+
+ /* Chunk size */
+ _wav_encoder_write_le(riff_header.chunk_size,
+ 4 + sizeof(fmt_header) + sizeof(data_header) + state->used,
+ sizeof(riff_header.chunk_size));
+
+ audio_stream_write_encoded(audio,
+ (unsigned char*) &riff_header,
+ sizeof(riff_header));
+
+ /*
+ * FMT HEADER
+ */
+
+ /* Channels */
+ _wav_encoder_write_le(fmt_header.subchunk_channels,
+ audio->channels, sizeof(fmt_header.subchunk_channels));
+
+ /* Sample rate */
+ _wav_encoder_write_le(fmt_header.subchunk_sample_rate,
+ audio->rate, sizeof(fmt_header.subchunk_sample_rate));
+
+ /* Byte rate */
+ _wav_encoder_write_le(fmt_header.subchunk_byte_rate,
+ audio->rate * audio->channels * audio->bps / 8,
+ sizeof(fmt_header.subchunk_byte_rate));
+
+ /* Block align */
+ _wav_encoder_write_le(fmt_header.subchunk_block_align,
+ audio->channels * audio->bps / 8,
+ sizeof(fmt_header.subchunk_block_align));
+
+ /* Bits per second */
+ _wav_encoder_write_le(fmt_header.subchunk_bps,
+ audio->bps, sizeof(fmt_header.subchunk_bps));
+
+ audio_stream_write_encoded(audio,
+ (unsigned char*) &fmt_header,
+ sizeof(fmt_header));
+
+ /*
+ * DATA HEADER
+ */
+
+ /* PCM data size */
+ _wav_encoder_write_le(data_header.subchunk_size,
+ state->used, sizeof(data_header.subchunk_size));
+
+ audio_stream_write_encoded(audio,
+ (unsigned char*) &data_header,
+ sizeof(data_header));
+
+ /* Write .wav data */
+ audio_stream_write_encoded(audio, state->data_buffer, state->used);
+
+ /* Free stream state */
+ free(state);
+
+}
+
+void wav_encoder_write_handler(audio_stream* audio,
+ unsigned char* pcm_data, int length) {
+
+ /* Get state */
+ wav_encoder_state* state = (wav_encoder_state*) audio->data;
+
+ /* Increase size of buffer if necessary */
+ if (state->used + length > state->length) {
+
+ /* Increase to double concatenated size to accomodate */
+ state->length = (state->length + length)*2;
+ state->data_buffer = realloc(state->data_buffer,
+ state->length);
+
+ }
+
+ /* Append to buffer */
+ memcpy(&(state->data_buffer[state->used]), pcm_data, length);
+ state->used += length;
+
+}
+
+/* Encoder handlers */
+audio_encoder _wav_encoder = {
+ .mimetype = "audio/wav",
+ .begin_handler = wav_encoder_begin_handler,
+ .write_handler = wav_encoder_write_handler,
+ .end_handler = wav_encoder_end_handler
+};
+
+/* Actual encoder */
+audio_encoder* wav_encoder = &_wav_encoder;
+
|
|
Added |
libguac-client-rdp-0.7.2.tar.bz2
^
|