$ git clone http://tcclient.ion.nu/tc_client.git
commit 2b1624b7cb264087519b487b0fd3508becccdc34
Author: Alicia <...>
Date: Sat Oct 8 01:52:10 2016 +0200
libcamera: added support for a virtual X11 camera.
diff --git a/ChangeLog b/ChangeLog
index 4bf9b0f..32b2949 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -20,6 +20,7 @@ tc_client-gtk: fixed resampling of incoming audio.
tc_client-gtk: added GTK+2 compatibility code related to the greenscreen camera color picker.
tc_client-gtk: added compatibility code for windows' lack of pipe()
tc_client-gtk: added workaround for libao not handling the "client_name" option on windows.
+libcamera: added support for a virtual X11 camera.
tc_client-gtk and camviewer: updated to libavcodec's avcodec_{send,receive}_{frame,packet} API.
camviewer: removed the old, buggy audio code.
libcamera(v4l2): cache the frame and if there is no data to be read, return the cache instead of blocking.
diff --git a/Makefile b/Makefile
index b1fa0c3..ae86c88 100644
--- a/Makefile
+++ b/Makefile
@@ -72,6 +72,11 @@ ifdef SWSCALE_LIBS
else
CONFINFO+=| v4l2 camera support will not be enabled
endif
+ ifdef LIBX11_LIBS
+ CONFINFO+=| Will enable X11 virtual camera support
+ CFLAGS+=-DHAVE_X11 $(LIBX11_CFLAGS)
+ LIBCAMERA_OBJ+=utilities/libcamera/camera_x11.o
+ endif
endif
endif
endif
@@ -107,13 +112,13 @@ modbot: $(MODBOT_OBJ)
$(CC) $(LDFLAGS) $^ $(LIBS) $(CURL_LIBS) -o $@
camviewer: $(CAMVIEWER_OBJ)
- $(CC) $(LDFLAGS) $^ $(LIBS) $(GTK_LIBS) $(AVCODEC_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(AVRESAMPLE_LIBS) $(SWRESAMPLE_LIBS) $(AO_LIBS) $(LIBV4L2_LIBS) -o $@
+ $(CC) $(LDFLAGS) $^ $(LIBS) $(GTK_LIBS) $(AVCODEC_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(AVRESAMPLE_LIBS) $(SWRESAMPLE_LIBS) $(AO_LIBS) $(LIBV4L2_LIBS) $(LIBX11_LIBS) -o $@
cursedchat: $(CURSEDCHAT_OBJ)
$(CC) $(LDFLAGS) $^ $(LIBS) $(READLINE_LIBS) $(CURSES_LIBS) -o $@
tc_client-gtk: $(TC_CLIENT_GTK_OBJ) camplaceholder.gif
- $(CC) $(LDFLAGS) $(TC_CLIENT_GTK_OBJ) $(LIBS) $(GTK_LIBS) $(AVCODEC_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(AVRESAMPLE_LIBS) $(SWRESAMPLE_LIBS) $(AO_LIBS) $(LIBV4L2_LIBS) -o $@
+ $(CC) $(LDFLAGS) $(TC_CLIENT_GTK_OBJ) $(LIBS) $(GTK_LIBS) $(AVCODEC_LIBS) $(AVUTIL_LIBS) $(SWSCALE_LIBS) $(AVRESAMPLE_LIBS) $(SWRESAMPLE_LIBS) $(AO_LIBS) $(LIBV4L2_LIBS) $(LIBX11_LIBS) -o $@
camplaceholder.gif: utilities/gtk/gencamplaceholder.sh utilities/gtk/camplaceholder.xcf utilities/gtk/spinnerdot.xcf
utilities/gtk/gencamplaceholder.sh
@@ -133,7 +138,7 @@ SOURCES+=utilities/cursedchat/cursedchat.c utilities/cursedchat/buffer.c utiliti
SOURCES+=utilities/gtk/camviewer.c utilities/gtk/userlist.c utilities/gtk/media.c utilities/gtk/compat.c utilities/gtk/config.c utilities/gtk/gui.c utilities/gtk/logging.c utilities/gtk/postproc.c utilities/gtk/inputhistory.c utilities/gtk/userlist.h utilities/gtk/media.h utilities/gtk/compat.h utilities/gtk/config.h utilities/gtk/gui.h utilities/gtk/logging.h utilities/gtk/postproc.h utilities/gtk/inputhistory.h gtkgui.glade
SOURCES+=utilities/gtk/gencamplaceholder.sh utilities/gtk/camplaceholder.xcf utilities/gtk/spinnerdot.xcf
SOURCES+=utilities/compat.c utilities/compat.h utilities/list.c utilities/list.h utilities/stringutils.c utilities/stringutils.h utilities/compat_av.c utilities/compat_av.h
-SOURCES+=utilities/libcamera/camera.c utilities/libcamera/camera.h utilities/libcamera/camera_v4l2.c utilities/libcamera/camera_v4l2.h utilities/libcamera/camera_img.c utilities/libcamera/camera_img.h utilities/libcamera/camera_escapi.cpp utilities/libcamera/camera_escapi.h
+SOURCES+=utilities/libcamera/camera.c utilities/libcamera/camera.h utilities/libcamera/camera_v4l2.c utilities/libcamera/camera_v4l2.h utilities/libcamera/camera_img.c utilities/libcamera/camera_img.h utilities/libcamera/camera_escapi.cpp utilities/libcamera/camera_escapi.h utilities/libcamera/camera_x11.c utilities/libcamera/camera_x11.h
tarball:
tar -cJf tc_client-$(VERSION).tar.xz --transform='s|^|tc_client-$(VERSION)/|' $(SOURCES)
diff --git a/configure b/configure
index 2865aea..8868c34 100755
--- a/configure
+++ b/configure
@@ -252,6 +252,16 @@ else
echo no
fi
+printf 'Checking for X11... '
+x11libs="`pkg-config --libs x11 2> /dev/null`"
+if [ "x$x11libs" != "x" ]; then
+ echo "LIBX11_LIBS=${x11libs}" >> config.mk
+ echo "LIBX11_CFLAGS=`pkg-config --cflags x11`" >> config.mk
+ echo yes
+else
+ echo no
+fi
+
# TODO: handle crosscompiling better
printf 'Checking if endianness macros work... '
echo '#include <stdio.h>' > endiantest.c
diff --git a/utilities/libcamera/camera.c b/utilities/libcamera/camera.c
index e5b2603..95a638b 100644
--- a/utilities/libcamera/camera.c
+++ b/utilities/libcamera/camera.c
@@ -1,6 +1,6 @@
/*
libcamera, a camera access abstraction library
- Copyright (C) 2015 alicia@ion.nu
+ Copyright (C) 2015-2016 alicia@ion.nu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@@ -18,6 +18,7 @@
#include "camera.h"
#include "camera_v4l2.h"
#include "camera_escapi.h"
+#include "camera_x11.h"
#include "camera_img.h"
struct CAM_t
@@ -35,6 +36,9 @@ char** cam_list(unsigned int* count)
#ifdef HAVE_ESCAPI
list=cam_list_escapi(list, count);
#endif
+ #ifdef HAVE_X11
+ list=cam_list_x11(list, count);
+ #endif
list=cam_list_img(list, count);
return list;
}
@@ -47,6 +51,9 @@ CAM* cam_open(const char* name)
#ifdef HAVE_ESCAPI
if(!strncmp(name, "escapi:", 7)){return cam_open_escapi(name);}
#endif
+ #ifdef HAVE_X11
+ if(!strcmp(name, "X11")){return cam_open_x11();}
+ #endif
if(!strcmp(name, "Image")){return cam_open_img();}
return 0;
}
@@ -61,6 +68,9 @@ void cam_resolution(CAM* cam, unsigned int* width, unsigned int* height)
#ifdef HAVE_ESCAPI
case CAMTYPE_ESCAPI: cam_resolution_escapi(cam, width, height); break;
#endif
+ #ifdef HAVE_X11
+ case CAMTYPE_X11: cam_resolution_x11(cam, width, height); break;
+ #endif
case CAMTYPE_IMG: cam_resolution_img(cam, width, height); break;
}
}
@@ -75,6 +85,9 @@ void cam_getframe(CAM* cam, void* pixmap)
#ifdef HAVE_ESCAPI
case CAMTYPE_ESCAPI: cam_getframe_escapi(cam, pixmap); break;
#endif
+ #ifdef HAVE_X11
+ case CAMTYPE_X11: cam_getframe_x11(cam, pixmap); break;
+ #endif
case CAMTYPE_IMG: cam_getframe_img(cam, pixmap); break;
}
}
@@ -89,6 +102,9 @@ void cam_close(CAM* cam)
#ifdef HAVE_ESCAPI
case CAMTYPE_ESCAPI: cam_close_escapi(cam); break;
#endif
+ #ifdef HAVE_X11
+ case CAMTYPE_X11: cam_close_x11(cam); break;
+ #endif
case CAMTYPE_IMG: cam_close_img(cam); break;
}
}
diff --git a/utilities/libcamera/camera.h b/utilities/libcamera/camera.h
index 6cf4776..77d17b4 100644
--- a/utilities/libcamera/camera.h
+++ b/utilities/libcamera/camera.h
@@ -1,6 +1,6 @@
/*
libcamera, a camera access abstraction library
- Copyright (C) 2015 alicia@ion.nu
+ Copyright (C) 2015-2016 alicia@ion.nu
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
@@ -19,7 +19,8 @@
enum{
CAMTYPE_V4L2,
CAMTYPE_ESCAPI,
- CAMTYPE_IMG
+ CAMTYPE_IMG,
+ CAMTYPE_X11
};
struct CAM_t;
typedef struct CAM_t CAM;
diff --git a/utilities/libcamera/camera_x11.c b/utilities/libcamera/camera_x11.c
new file mode 100644
index 0000000..7ca76a8
--- /dev/null
+++ b/utilities/libcamera/camera_x11.c
@@ -0,0 +1,85 @@
+/*
+ libcamera, a camera access abstraction library
+ Copyright (C) 2016 alicia@ion.nu
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <stdlib.h>
+#include <string.h>
+#include <X11/Xlib.h>
+#include "camera.h"
+typedef struct CAM_t
+{
+ unsigned int type;
+ Display* display;
+ int screen;
+ Window rootwindow;
+ int width;
+ int height;
+} CAM;
+
+char** cam_list_x11(char** list, unsigned int* count)
+{
+ ++*count;
+ list=realloc(list, sizeof(char*)*(*count));
+ list[(*count)-1]=strdup("X11");
+ return list;
+}
+
+CAM* cam_open_x11(void) // const char* name)
+{
+ Display* display=XOpenDisplay(getenv("DISPLAY"));
+ if(!display){return 0;}
+ CAM* cam=malloc(sizeof(CAM));
+ cam->type=CAMTYPE_X11;
+ cam->display=display;
+ cam->screen=XDefaultScreen(display);
+ cam->width=DisplayWidth(cam->display, cam->screen);
+ cam->height=DisplayHeight(cam->display, cam->screen);
+ cam->rootwindow=RootWindow(cam->display, cam->screen);
+ return cam;
+}
+
+void cam_resolution_x11(CAM* cam, unsigned int* width, unsigned int* height)
+{
+ *width=cam->width;
+ *height=cam->height;
+}
+
+void cam_getframe_x11(CAM* cam, void* pixmap)
+{
+ XImage* img=XGetImage(cam->display, cam->rootwindow, 0, 0, cam->width, cam->height, AllPlanes, ZPixmap);
+ unsigned int bpp=img->bits_per_pixel/8;
+ unsigned int x, y;
+ for(y=0; y<cam->height; ++y)
+ {
+ for(x=0; x<cam->width; ++x)
+ {
+ if(img->blue_mask>img->red_mask)
+ {
+ memcpy(pixmap+(y*cam->width+x)*3, img->data+y*img->bytes_per_line+x*bpp, 3);
+ }else{
+ memcpy(pixmap+(y*cam->width+x)*3+2, img->data+y*img->bytes_per_line+x*bpp, 1);
+ memcpy(pixmap+(y*cam->width+x)*3+1, img->data+y*img->bytes_per_line+x*bpp+1, 1);
+ memcpy(pixmap+(y*cam->width+x)*3, img->data+y*img->bytes_per_line+x*bpp+2, 1);
+ }
+ }
+ }
+ img->f.destroy_image(img);
+}
+
+void cam_close_x11(CAM* cam)
+{
+ XCloseDisplay(cam->display);
+ free(cam);
+}
diff --git a/utilities/libcamera/camera_x11.h b/utilities/libcamera/camera_x11.h
new file mode 100644
index 0000000..6b87c21
--- /dev/null
+++ b/utilities/libcamera/camera_x11.h
@@ -0,0 +1,21 @@
+/*
+ libcamera, a camera access abstraction library
+ Copyright (C) 2016 alicia@ion.nu
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, version 3 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+extern char** cam_list_x11(char** list, unsigned int* count);
+extern CAM* cam_open_x11(void);
+extern void cam_resolution_x11(CAM* cam, unsigned int* width, unsigned int* height);
+extern void cam_getframe_x11(CAM* cam, void* pixmap);
+extern void cam_close_x11(CAM* cam);